edwith에서 수강하던 강좌를 마쳤다. ( Swift 기초문법 )
우선은 Swift문법은 100% 다 익히고 응용할 수 있는 단계는 아니지만, 그래도 예제 코드나 이후 진행되는 프로그래밍 관련해서 보고 알아 볼 수 있는 정도의 수준은 되었다.
이번 강좌도 edwith에서 수강한다.
iOS프로그래밍 이라는 강좌이며 오리엔테이션과 총 5개의 프로젝트를 진행 하는 것 같다.
아무래도 어플을 만드는거다 보니, 기존 기초문법 강좌보다 디테일하게 설명하는 부분은 많지 않다.
( 사용메소드 하나하나 사용법과 그 정의를 확인해가면서 하면 강좌가 진행될 수 없을 것이다 ... )
스위프트는 아니더라도 나름 개발 경력을 가지고 있기 때문에 흐름(?)상 어떤 느낌인지 알겠더라.
( 경력에 감사! )
그래도 내 블로그를 봐주는 사람들과, 그리고 미래의 내가 코드를 보고 못알아 볼 수 있기 때문에 강좌에서 설명하지 않은 부분도 짧게나마 주석으로 간단한 설명을 할 예정이다.
Xcode 사용
현재 나는 window로만 개발을 했기 때문에 Mac OS자체가 생소하고, 거기에 Xcode는 당연히 처음 쓴다.
그래서 블로그에 XCode사용법부터 작성해야 할까? 생각도 많이 했지만 구글을 통해 검색을 좀 해보니 굳이 내가 하지 않아도 되겠더라.
너무 많은 블로거들이 너무나도 정성스럽게 Xcode사용법을 작성했고, 나는 그정도의 퀄리티가 있는 포스팅을 할 자신이 없어졌다 .. ㅋㅋㅋ ( 귀찮아서 아님. )
따라서 별도의 Xcode사용법으로 포스팅을 진행 하지는 않고, 향후에 예제를 진행 하다가 ' 오 이거 꿀팁! ' 이라고 생각 되는 부분이 있다면 그때그때 포스팅을 할 생각이다.
음악 재생 앱
하나의 페이지에 음악재생을 제어하는 앱이다.
주어진 요구사항은 아래와 같다.
[ 요구사항 ]
- 하나의 페이지로 구성한다
- 재생 이미지와 정지이미지를 이용하여 현재 오디오가 재생 중인지 정지 중인지 확인 할 수 있어야 한다
- 이미지 버튼을 클릭하면 재생, 정지 기능이 동작 해야 한다
- 재생중인 음악의 시간을 사용자가 텍스트를 이용해 확인이 가능해야 한다
- 슬라이더를 이용하여 원하는 재생 시간대로 이동할 수 있어야 한다
- 재생이 종료되면 아이콘이 재생 아이콘으로 변경되어야 한다.
소스코드
import UIKit
import AVFoundation
class ViewController: UIViewController, AVAudioPlayerDelegate {
var player : AVAudioPlayer!
var timer : Timer!
@IBOutlet weak var playBtn: UIButton!
@IBOutlet weak var playTimeLabel: UILabel!
@IBOutlet weak var playSilder: UISlider!
// 재생 버튼을 클릭하면
@IBAction func touchUpPlayPauseBtn( sender : UIButton){
print("btn change");
sender.isSelected = !sender.isSelected
// sender가 선택되면 플레이어가 재생중인지 확인하고 처리
if sender.isSelected {
self.player?.play()
} else {
self.player?.pause()
}
// sender가 선택되면 타이머 처리를 할 것인지 확인
if sender.isSelected{
self.mamkeAndFireTimer()
} else{
self.invalidateTimer()
}
}
// 플레이어 초기화.
func initializePlayer(){
guard let soundAsset : NSDataAsset = NSDataAsset(name : "sound") else {
print("음원없음");
return;
}
do {
try self.player = AVAudioPlayer(data : soundAsset.data);
self.player.delegate = self;
} catch let error as NSError {
print("초기화 실패");
print("코드 : \(error.code), 메세지 : \(error.localizedDescription) ");
}
self.playSilder.maximumValue = Float(self.player.duration);
self.playSilder.minimumValue = 0;
self.playSilder.value = Float(self.player.currentTime);
}
// 레이블 업데이트.
func updateTimeLabelText(time:TimeInterval){
let minute : Int = Int(time/60);
let second : Int = Int(time.truncatingRemainder(dividingBy: 60));
let milisecond : Int = Int(time.truncatingRemainder(dividingBy: 1)*100);
let timeText : String = String(format : "%02ld:%02ld:%02ld", minute, second, milisecond);
self.playTimeLabel.text = timeText;
}
// 타이머를 만들고 수행해줄 메소드
func mamkeAndFireTimer(){
self.timer = Timer.scheduledTimer(withTimeInterval : 0.01, repeats: true, block : { [unowned self] (timer : Timer) in
if self.playSilder.isTracking { return };
self.updateTimeLabelText(time:self.player.currentTime);
self.playSilder.value = Float(self.player.currentTime);
})
self.timer.fire();
}
// 플레이어 재생 관련 에러처리.
func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
guard let error: Error = error else{
print("플레이어 오류 발생");
return
}
let message : String
message = "플레이어 오류 발생 \(error.localizedDescription)";
let alert : UIAlertController = UIAlertController(title:"알림", message : message, preferredStyle :UIAlertController.Style.alert);
let okAction : UIAlertAction = UIAlertAction(title : "확인", style : UIAlertAction.Style.default) { ( action:UIAlertAction) -> Void in
self.dismiss(animated: true, completion:nil)
}
alert.addAction(okAction)
self.present(alert, animated:true, completion:nil)
}
// 음악 재생이 끝나면
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
self.playBtn.isSelected = false;
self.playSilder.value = 0;
self.updateTimeLabelText(time: 0)
self.invalidateTimer()
}
// 타이머 해제
func invalidateTimer(){
self.timer.invalidate();
self.timer = nil;
}
override func viewDidLoad() {
super.viewDidLoad()
self.initializePlayer();
// Do any additional setup after loading the view, typically from a nib.
}
// 슬라이더를 이용한 오디오 제어
@IBAction func sliderValueControl(_ sender: UISlider) {
self.updateTimeLabelText(time: TimeInterval(sender.value))
if sender.isTracking{return}
self.player.currentTime = TimeInterval(sender.value);
}
}
코드내용은 위와 같다.
( 이거 또한 iOS프로그래밍 동영상 강좌에서 나오는 소스코드를 직접 타이핑하여 작성한 것이다. )
보면 크게 어려운 내용은 없다. 문법공부를 미리 해서 코드상에서 딱히 해석이 되지 않는 것은 없는데,
공부하면서 배우지 않은 메소드들이 조금 생소할 뿐이다.
예를 들면 UIAlertController가 있는데 ,
완성된 앱의 형태
let alert : UIAlertController = UIAlertController(title:"알림", message : message, preferredStyle :UIAlertController.Style.alert);
let okAction : UIAlertAction = UIAlertAction(title : "확인", style : UIAlertAction.Style.default) { ( action:UIAlertAction) -> Void in
self.dismiss(animated: true, completion:nil)
강의 내용과 현재 사용하고자 할 때 조금 문법이 달라 찾아보았다.
//강좌에서는
preferredStyle : UIAlertControllerStyle.alert
style : UIAlertActionStyle.default
//실제 사용하려면..
preferredStyle :UIAlertController.Style.alert
style : UIAlertAction.Style.default
이부분 외에는 크게 다른 내용이 없기 때문에 앱을 개발하는데 큰 문제는 없었다.
예제를 작성하면서 '오!?' 했었던 것은 버튼의 이미지를 지정해 줄 때 기본 이미지와 셀렉트 되었을때 이미지를 따로 지정할 수 있었던 것이 조금 놀라웠고 ( 안드로이드에서도 가능한가??? 사용해 본적이 없었던 것으로 ... ;; )
생각보다 UI를 만들고 Action을 설정하는데 편리하다고 느낄법 했다.
표현이 조금 이상한데, 안드로이드 개발자 기준으로는 xml코딩으로 레이아웃을 잡는게 아직은 조금 더 편하다. iOS의 경우 드래그앤드롭으로 UI와 연결되는 변수를 만들어 줄 수 있고, 심지어 연결되는 메소드(이벤트 리스너 같은.. )를 만들 수 있다.
'Develop > iOS' 카테고리의 다른 글
iOS 오토레이아웃 ( AutoLayout ) (0) | 2019.05.14 |
---|---|
iOS 음악 재생 앱 만들기 Part#2 - Audio Method (0) | 2019.05.14 |
Swift 오류 처리 ( Error ) (0) | 2019.05.13 |
Swift 익스텐션 (0) | 2019.05.13 |
Swift 프로토콜 (Protocol) (0) | 2019.05.10 |