AVAudio Player v AVAudio Player Delegate audio Player

  • Slides: 91
Download presentation

AVAudio. Player v AVAudio. Player. Delegate ü audio. Player. Did. Finish. Playing: 오디오 재생

AVAudio. Player v AVAudio. Player. Delegate ü audio. Player. Did. Finish. Playing: 오디오 재생 끝나는 경우 호출 ü audio. Player. Decode. Error. Did. Occur: 오디오 재생 도중 디코딩 에러가 발생하는 경우 ü audio. Player. Begin. Interruption: 시스템 이벤트에 의해 오디오 재생이 멈춰졌을 때 호출 ü audio. Player. End. Interruption: 시스템 이벤트가 종료되었을 때 호출

내장 사운드 이용 v System/Library/Audio/UISounds 디렉토리에는 아이폰이 사용하는 내장 사운드 파일이 존재 v 파일명

내장 사운드 이용 v System/Library/Audio/UISounds 디렉토리에는 아이폰이 사용하는 내장 사운드 파일이 존재 v 파일명 Received. Message. caf, Ringer. Changed. caf, SIMToolkit. Call. Dropped. caf 등 v 사용 예 let path = "System/Library/Audio/UISounds/SIMToolkit. General. Beep. caf" let dir. Paths = NSSearch. Path. For. Directories. In. Domains(. document. Directory, . user. Domain. Mask, true) let docs. Dir = dir. Paths[0] let file = docs. Dir + "/test. caf" print(file) try! File. Manager. default. copy. Item(at. Path: path, to. Path: file)

예제 – 사운드 재생 v Single View Application 프로젝트 생성(Multimedia. Use) v Main. storyboard

예제 – 사운드 재생 v Single View Application 프로젝트 생성(Multimedia. Use) v Main. storyboard 파일의 View. Controller의 View에 2개의 버튼과 1개의 슬라이더를 배치하고 2개의 버튼에 touch. Up. Inside 이벤트에 메소드(audio. Play, audio. Stop)를 연결하고 슬라이더는 value. Changed 이벤트에 메 소드(change. Volumn) 연결

예제 – 사운드 재생 v 프로젝트에 노래 파일(test. mp 3) 추가 v View. Controller.

예제 – 사운드 재생 v 프로젝트에 노래 파일(test. mp 3) 추가 v View. Controller. swift 파일에 헤더파일을 import AVFoundation v View. Controller. swift 파일에 인스턴스 변수 선언 var audio. Player: AVAudio. Player?

예제 – 사운드 재생 v View. Controller. swift 파일의 view. Did. Load 메서드 수정

예제 – 사운드 재생 v View. Controller. swift 파일의 view. Did. Load 메서드 수정 override func view. Did. Load() { super. view. Did. Load() let url = URL(file. URLWith. Path: Bundle. main. path(for. Resource: "test", of. Type: "mp 3")!, relative. To: nil) /* let path = "System/Library/Audio/UISounds/SIMToolkit. General. Beep. caf" let dir. Paths = NSSearch. Path. For. Directories. In. Domains(. document. Directory, . user. Domain. Mask, true) let docs. Dir = dir. Paths[0] let file = docs. Dir + "/test 1. caf" print(file) try! File. Manager. default. copy. Item(at. Path: path, to. Path: file) */ //let url = URL(file. URLWith. Path: file, relative. To: nil) print(url) audio. Player = try! AVAudio. Player(contents. Of: url) audio. Player!. prepare. To. Play() }

예제 – 사운드 재생 v View. Controller. swift 파일의 이벤트 처리 메서드 수정 @IBAction

예제 – 사운드 재생 v View. Controller. swift 파일의 이벤트 처리 메서드 수정 @IBAction func audio. Play(_ sender: Any) { if let player = audio. Player { player. play() } } @IBAction func audio. Stop(_ sender: Any) { if let player = audio. Player { player. stop() } } @IBAction func change. Volumn(_ sender: Any) { if audio. Player != nil { let slider = sender as! UISlider audio. Player? . volume = slider. value } }

백그라운드 음악 재생 v 음원 재생 코드 수정 @IBAction func audio. Play(_ sender: Any)

백그라운드 음악 재생 v 음원 재생 코드 수정 @IBAction func audio. Play(_ sender: Any) { /* if let player = audio. Player { player. play() } */ let session = AVAudio. Session. shared. Instance() do { try session. set. Category(AVAudio. Session. Category. playback, mode: . default, policy: AVAudio. Session. Route. Sharing. Policy. long. Form. Audio, options: []) } catch let error { fatal. Error("*** Unable to set up the audio session: (error. localized. Description) ***") } if let player = audio. Player { player. play() } }

소리 녹음 v AVFoundation 프레임워크의 AVAudio. Recorder 클래스를 이용 v 메서드와 프로퍼티 ü init(url:

소리 녹음 v AVFoundation 프레임워크의 AVAudio. Recorder 클래스를 이용 v 메서드와 프로퍼티 ü init(url: URL, settings: [String : Any]) throws ü prepare. To. Record ü record. For. Duration: ü pause ü stop ü delete. Recording ü delegate v Settings ü AVNumber. Of. Channels. Key: 1(모노) 또는 2(스테레오) ü AVFormat. IDKey: k. Audio. Format. Linear. PCM(대용량), k. Audio. Format. Apple. IMA 4(소용량) ü AVSample. Rate. Key: 샘플링비율로 8000, 11025, 22025, 44100 등으로 설정

소리 녹음 v 오디오 레벨 ü metering. Enabled => 오디오 레벨 측정 여부를 설정

소리 녹음 v 오디오 레벨 ü metering. Enabled => 오디오 레벨 측정 여부를 설정 ü average. Power. For. Channel: => 채널의 평균 레벨 ü peak. Power. For. Channel: => 채널의 최대 레벨 ü update. Meters => 현재 레벨 v delegate 메서드 ü audio. Recorder. Did. Finish. Recording: successfully: ü audio. Recorder. Encode. Error. Did. Occur: error:

예제 – 사운드 녹음 v Main. storyboard 파일의 View. Controller의 view에 3개의 버튼을 배치하고

예제 – 사운드 녹음 v Main. storyboard 파일의 View. Controller의 view에 3개의 버튼을 배치하고 touch. Up. Inside 이벤트에 메소드 (audio. Record. Start, audio. Record. Stop, record. Audio. Playt)를 연결하고 변수와 연결(bnt. Start, btn. Stop, btn. Play) v View. Controller 클래스에 멤버 변수 선언 var player: AVAudio. Player? var audio. Recorder: AVAudio. Recorder?

예제 – 사운드 녹음 v View. Controller 클래스의 View. Did. Load 메서드에 코드 추가

예제 – 사운드 녹음 v View. Controller 클래스의 View. Did. Load 메서드에 코드 추가 btn. Play. is. Enabled = false btn. Stop. is. Enabled = false let dir. Paths = NSSearch. Path. For. Directories. In. Domains(. document. Directory, . user. Domain. Mask, true) let docs. Dir = dir. Paths[0] let sound. File. Path = docs. Dir + "/sound. caf" let sound. File. URL = URL(file. URLWith. Path: sound. File. Path) let record. Settings: [String: Any] = [AVEncoder. Audio. Quality. Key: AVAudio. Quality. min. raw. Value, AVEncoder. Bit. Rate. Key: 16, AVNumber. Of. Channels. Key: 2, AVSample. Rate. Key: 44100. 0] let audio. Session = AVAudio. Session. shared. Instance() try! audio. Session. set. Category(AVAudio. Session. Category. play. And. Record) audio. Recorder = try! AVAudio. Recorder(url: sound. File. URL, settings: record. Settings) audio. Recorder? . prepare. To. Record()

예제 – 사운드 녹음 v View. Controller 클래스에 버튼의 이벤트 처리 메서드 수정 @IBAction

예제 – 사운드 녹음 v View. Controller 클래스에 버튼의 이벤트 처리 메서드 수정 @IBAction func audio. Record. Start(_ sender: Any) { if audio. Recorder? . is. Recording == false { btn. Play. is. Enabled = false btn. Stop. is. Enabled = true audio. Recorder? . record() } }

예제 – 사운드 녹음 v View. Controller 클래스에 버튼의 이벤트 처리 메서드 수정 @IBAction

예제 – 사운드 녹음 v View. Controller 클래스에 버튼의 이벤트 처리 메서드 수정 @IBAction func audio. Record. Stop(_ sender: Any) { btn. Stop. is. Enabled = false btn. Play. is. Enabled = true btn. Start. is. Enabled = true if audio. Recorder? . is. Recording == true { audio. Recorder? . stop() } else { player? . stop() } }

예제 – 사운드 녹음 v View. Controller 클래스에 버튼의 이벤트 처리 메서드 수정 @IBAction

예제 – 사운드 녹음 v View. Controller 클래스에 버튼의 이벤트 처리 메서드 수정 @IBAction func record. Audio. Play(_ sender: Any) { if audio. Recorder? . is. Recording == false { btn. Stop. is. Enabled = true btn. Start. is. Enabled = false player = try! AVAudio. Player(contents. Of: audio. Recorder!. url) player? . delegate = self player? . play() } }

예제 – 사운드 녹음 v View. Controller. swift 파일에 extension을 추가하고 AVAudio. Player. Delegate

예제 – 사운드 녹음 v View. Controller. swift 파일에 extension을 추가하고 AVAudio. Player. Delegate 메서드 작성 extension View. Controller: AVAudio. Player. Delegate{ func audio. Player. Did. Finish. Playing(_ player: AVAudio. Player, successfully flag: Bool) { btn. Start. is. Enabled = true btn. Stop. is. Enabled = false } func audio. Player. Decode. Error. Did. Occur(_ player: AVAudio. Player, error: Error? ) { print("Audio Play Decode Error") } func audio. Recorder. Did. Finish. Recording(_ recorder: AVAudio. Recorder, successfully flag: Bool) { } func audio. Recorder. Encode. Error. Did. Occur(_ recorder: AVAudio. Recorder, error: Error? ) { print("Audio Record Encode Error") } }

예제 – 비디오 재생 v Main. storyboard 파일의 View. Controller의 View에 버튼을 2개 추가

예제 – 비디오 재생 v Main. storyboard 파일의 View. Controller의 View에 버튼을 2개 추가 v Main. storyboard 파일에 AVKit Player View Controller를 추가

예제 – 비디오 재생 v View. Controller. swift 파일에 AVKit import AVKit v View.

예제 – 비디오 재생 v View. Controller. swift 파일에 AVKit import AVKit v View. Controller. swift 파일에 segue로 이동하기 전에 호출되는 메서드 재정의 override func prepare(for segue: UIStoryboard. Segue, sender: Any? ) { let destination = segue. destination as! AVPlayer. View. Controller let url = URL(string: "http: //www. ebookfrenzy. com/ios_book/movie. mov") //let file. Path: String? = Bundle. main. path(for. Resource: "IPhone 3 G", of. Type: "mov") //let url = URL(file. URLWith. Path: file. Path!) destination. player = AVPlayer(url: url!) } v info. plist 파일에 추가 <key>NSApp. Transport. Security</key> <dict> <key>NSAllows. Arbitrary. Loads</key> <true/> </dict>

예제 – 비디오 재생 v 버튼의 touch. Up. Inside 이벤트에 메소드 연결 v View.

예제 – 비디오 재생 v 버튼의 touch. Up. Inside 이벤트에 메소드 연결 v View. Controller. swift 파일의 버튼 클릭 이벤트 처리 메서드 작성 @IBAction func video. Play(_ sender: Any) { let file. Path: String? = Bundle. main. path(for. Resource: "IPhone 3 G", of. Type: "mov") let url = URL(file. URLWith. Path: file. Path!) let player = AVPlayer(url: url) let player. Controller = AVPlayer. View. Controller() player. Controller. player = player self. add. Child(player. Controller) self. view. add. Subview(player. Controller. view) player. Controller. view. frame = self. view. frame player. play() }

i. OS에서의 Multi. Tasking v AVPlayer. View. Controller. Delegate 메소드 ü restore. User. Interface.

i. OS에서의 Multi. Tasking v AVPlayer. View. Controller. Delegate 메소드 ü restore. User. Interface. For. Picture. In. Picture. Stop. With. Completion. Handler: PIP 모드에서 전체 재생으로 변 경될 때 호출되는 메소드 ü player. View. Controller. Will. Start. Picture. In. Picture: PIP 모드로의 전환이 시작되기 전에 호출 ü player. View. Controller. Did. Start. Picture. In. Picture: PIP 모드로 재생이 시작되면 호출 ü func player. View. Controller. Will. Stop. Picture. In. Picture: PIP 모드로 재생이 정지되기 전에 호출 ü func player. View. Controller. Did. Stop. Picture. In. Picture: PIP 모드로 재생이 정지되기 전에 호출. ü func player. View. Controller(AVPlayer. View. Controller, failed. To. Start. Picture. In. Picture. With. Error: Error): PIP 모드 실패시 호출 33 33

i. OS에서의 Multi. Tasking 34 34

i. OS에서의 Multi. Tasking 34 34

i. OS에서의 Multi. Tasking v Main. stroyboard 파일에서 View. Controller 에 Navigation. Controller 추가

i. OS에서의 Multi. Tasking v Main. stroyboard 파일에서 View. Controller 에 Navigation. Controller 추가 : [Editor] – [Embed In] – [Navigation Controller] 35 35

i. OS에서의 Multi. Tasking v App. Delegate. swift 파일에 AVFoundataion import AVFoundation v App.

i. OS에서의 Multi. Tasking v App. Delegate. swift 파일에 AVFoundataion import AVFoundation v App. Delegate. swift 파일에 있는 did. Finish. Launching. With. Options 메소드에 추가 func application(_ application: UIApplication, did. Finish. Launching. With. Options launch. Options: [UIApplication. Launch. Options. Key: Any]? ) -> Bool { let audio. Session = AVAudio. Session. shared. Instance() do { try audio. Session. set. Category(AVAudio. Session. Category. playback) } catch { print("Unable to set audio session category") } return true } 36 36

i. OS에서의 Multi. Tasking v View. Controller. swift 파일에 prepare 메소드 수정 override func

i. OS에서의 Multi. Tasking v View. Controller. swift 파일에 prepare 메소드 수정 override func prepare(for segue: UIStoryboard. Segue, sender: Any? ) { let destination = segue. destination as! AVPlayer. View. Controller let url = URL(string: "http: //www. ebookfrenzy. com/ios_book/movie. mov") destination. delegate = self destination. player = AVPlayer(url: url!) } 37 37

i. OS에서의 Multi. Tasking v View. Controller. swift 파일의 extendsion메소드 수정 override func prepare(for

i. OS에서의 Multi. Tasking v View. Controller. swift 파일의 extendsion메소드 수정 override func prepare(for segue: UIStoryboard. Segue, sender: Any? ) { let destination = segue. destination as! AVPlayer. View. Controller let url = URL(string: "http: //www. ebookfrenzy. com/ios_book/movie. mov") destination. delegate = self destination. player = AVPlayer(url: url!) } 38 38

i. OS에서의 Multi. Tasking v View. Controller. swift 파일의 extendsion에 메소드 추가 extension View.

i. OS에서의 Multi. Tasking v View. Controller. swift 파일의 extendsion에 메소드 추가 extension View. Controller: AVAudio. Player. Delegate, AVPlayer. View. Controller. Delegate{ func player. View. Controller(_ player. View. Controller: AVPlayer. View. Controller, restore. User. Interface. For. Picture. In. Picture. Stop. With. Completion. Handler completion. Handler: @escaping (Bool) -> Void) { let current. View. Controller = navigation. Controller? . visible. View. Controller if current. View. Controller != player. View. Controller { if let top. View. Controller = navigation. Controller? . top. View. Controller { top. View. Controller. present(player. View. Controller, animated: true, completion: {() completion. Handler(true) }) } } 39 39

Image Picker Controller 42 42

Image Picker Controller 42 42

Image Picker Controller v 프로젝트 생성(Image. Picker. Use) v Main. storyboard 파일에 Button 2개

Image Picker Controller v 프로젝트 생성(Image. Picker. Use) v Main. storyboard 파일에 Button 2개 와 Image. View를 추가 43 43

Image Picker Controller v Button에는 pick 과 add. Server 라는 메소드를 touch. Up. Inside

Image Picker Controller v Button에는 pick 과 add. Server 라는 메소드를 touch. Up. Inside 이벤트에 연결 v Image. View에는 img. View라는 변수를 연결 44 44

Image Picker Controller v View. Controller. swift 파일의 pick 이라는 메소드에 아래 코드를 추가하고

Image Picker Controller v View. Controller. swift 파일의 pick 이라는 메소드에 아래 코드를 추가하고 실행해서 버튼을 클릭해서 테스트 @IBAction func pick(_ sender: Any) { // 이미지 피커 컨트롤러 인스턴스 생성 let picker = UIImage. Picker. Controller( ) picker. source. Type =. photo. Library // 이미지 소스로 사진 라이브러리 선택 picker. allows. Editing = true // 이미지 편집 기능 On // 이미지 피커 컨트롤러 실행 self. present(picker, animated: false) } 45 45

Image Picker Controller v View. Controller. swift 파일에 UIImage. Picker. Controller. Delegate 와 UINavigation.

Image Picker Controller v View. Controller. swift 파일에 UIImage. Picker. Controller. Delegate 와 UINavigation. Delegate 프로토콜을 conform 한 extension을 만들고 메소드 구현 //이미지 피커 컨트롤러 델리게이트 메소드 extension View. Controller: UIImage. Picker. Controller. Delegate{ // 이미지 피커에서 이미지를 선택하지 않고 취소했을 때 호출되는 메소드 func image. Picker. Controller. Did. Cancel(_ picker: UIImage. Picker. Controller){ self. dismiss(animated: false) { () in // 알림창 호출 let alert = UIAlert. Controller(title: "", message: "이미지 선택을 취소되었습니다", preferred. Style: . alert) alert. add. Action(UIAlert. Action(title: "확인", style: . cancel)) self. present(alert, animated: false) } } 47 47

Image Picker Controller v View. Controller. swift 파일에 UIImage. Picker. Controller. Delegate 와 UINavigation.

Image Picker Controller v View. Controller. swift 파일에 UIImage. Picker. Controller. Delegate 와 UINavigation. Delegate 프로토콜을 conform 한 extension을 만들고 메소드 구현 // 이미지 피커에서 이미지를 선택했을 때 호출되는 메소드 func image. Picker. Controller(_ picker: UIImage. Picker. Controller, did. Finish. Picking. Media. With. Info info: [UIImage. Picker. Controller. Info. Key : Any]){ // 이미지 피커 컨트롤러 창 닫기 picker. dismiss(animated: false) { () in // 이미지를 이미지 뷰에 표시 let img = info[UIImage. Picker. Controller. Info. Key. edited. Image] as? UIImage self. img. View. image = img } } } extension View. Controller: UINavigation. Controller. Delegate { } 48 48

Image Picker Controller v View. Controller. swift 파일의 pick 메소드에 picker의 delegate 설정 코드를

Image Picker Controller v View. Controller. swift 파일의 pick 메소드에 picker의 delegate 설정 코드를 추가 picker. delegate = self 49 49

Image Picker Controller v 프로젝트를 Alamofire 라이브러리를 사용할 수 있도록 수정 v View. Controller.

Image Picker Controller v 프로젝트를 Alamofire 라이브러리를 사용할 수 있도록 수정 v View. Controller. swift 파일에 Alamofire import Alamofire 50 50

Image Picker Controller v add. Server 메소드 구현 @IBAction func add. Server(_ sender: Any)

Image Picker Controller v add. Server 메소드 구현 @IBAction func add. Server(_ sender: Any) { let add. Alert = UIAlert. Controller(title: "데이터 추가", message: "추가할 데이터를 입력하세요", preferred. Style: . alert) add. Alert. add. Text. Field(){(tf) -> Void in tf. placeholder = "추가할 항목의 이름을 입력하세요"} add. Alert. add. Text. Field(){(tf) -> Void in tf. placeholder = "추가할 항목의 가격을 입력하세요" tf. keyboard. Type =. number. Pad} add. Alert. add. Text. Field(){(tf) -> Void in tf. placeholder = "추가할 항목의 설명을 입력하세요"} add. Alert. add. Action(UIAlert. Action(title: "취소", style: . cancel)) add. Alert. add. Action(UIAlert. Action(title: "추가", style: . default){ (_) in let itemname = add. Alert. text. Fields? [0]. text let price = add. Alert. text. Fields? [1]. text let description = add. Alert. text. Fields? [2]. text 51 51

Image Picker Controller v add. Server 메소드 구현 let parameter. S: Parameters = ["itemname":

Image Picker Controller v add. Server 메소드 구현 let parameter. S: Parameters = ["itemname": itemname!, "price": price!, "description": description!] AF. upload( multipart. Form. Data: { multipart. Form. Data in for (key, value) in parameter. S { if let temp = value as? String { multipart. Form. Data. append(temp. data(using: . utf 8)!, with. Name: key) } } let image = self. img. View. image if image != nil{ multipart. Form. Data. append(image!. png. Data()!, with. Name: "pictureurl" , file. Name: "file. png", mime. Type: "image/png") } }, to: "http: //cyberadam. cafe 24. com/item/insert", method: . post , headers: nil). validate(status. Code: 200. . <300). response. JSON { response in if let json. Object = response. value as? [String : Any]{ let result = json. Object["result"]! as? Bool var msg : String? if result! { msg = "삽입 성공" }else{ msg = "삽입 실패" } 52 52

Image Picker Controller v add. Server 메소드 구현 let msg. Alert = UIAlert. Controller(title:

Image Picker Controller v add. Server 메소드 구현 let msg. Alert = UIAlert. Controller(title: "데이터 삽입", message: msg, preferred. Style: . alert) msg. Alert. add. Action(UIAlert. Action(title: "확인", style: . default)) self. present(msg. Alert, animated: true) } } }) self. present(add. Alert, animated: true) } 53 53

Image Picker Controller v Info. plist 파일에 추가 <key>NSApp. Transport. Security</key> <dict> <key>NSAllows. Arbitrary.

Image Picker Controller v Info. plist 파일에 추가 <key>NSApp. Transport. Security</key> <dict> <key>NSAllows. Arbitrary. Loads</key> <true/> </dict> 54 54

카메라 v 3개 버튼의 touch. Up. Inside 이벤트에 메소드 연결: (take. Camera, take. Video,

카메라 v 3개 버튼의 touch. Up. Inside 이벤트에 메소드 연결: (take. Camera, take. Video, read. Video) v View. Controller에 import 하고 delegate conform import Mobile. Core. Services

카메라 v View. Controller에 인스턴스 변수 추가 let image. Picker: UIImage. Picker. Controller! =

카메라 v View. Controller에 인스턴스 변수 추가 let image. Picker: UIImage. Picker. Controller! = UIImage. Picker. Controller() var capture. Image: UIImage! var video. URL: URL! var flag. Image. Save = false

카메라 v View. Controller에 버튼의 이벤트 처리 메소드 구현 @IBAction func take. Camera(_ sender:

카메라 v View. Controller에 버튼의 이벤트 처리 메소드 구현 @IBAction func take. Camera(_ sender: Any) { if (UIImage. Picker. Controller. is. Source. Type. Available(. camera)) { flag. Image. Save = true image. Picker. delegate = self image. Picker. source. Type =. camera image. Picker. media. Types = [k. UTType. Image as String] image. Picker. allows. Editing = false present(image. Picker, animated: true, completion: nil) } else { let msg. Alert = UIAlert. Controller(title: "카메라", message: "카메라를 사용할 수 없음", preferred. Style: . alert) msg. Alert. add. Action(UIAlert. Action(title: "확인", style: . default)) present(msg. Alert, animated: true) } }

카메라 @IBAction func take. Video(_ sender: Any) { if (UIImage. Picker. Controller. is. Source.

카메라 @IBAction func take. Video(_ sender: Any) { if (UIImage. Picker. Controller. is. Source. Type. Available(. camera)) { flag. Image. Save = true image. Picker. delegate = self image. Picker. source. Type =. camera image. Picker. media. Types = [k. UTType. Movie as String] image. Picker. allows. Editing = false present(image. Picker, animated: true, completion: nil) } else { let msg. Alert = UIAlert. Controller(title: "카메라", message: "카메라를 사용할 수 없음", preferred. Style: . alert) msg. Alert. add. Action(UIAlert. Action(title: "확인", style: . default)) present(msg. Alert, animated: true) } }

카메라 @IBAction func read. Video(_ sender: Any) { if (UIImage. Picker. Controller. is. Source.

카메라 @IBAction func read. Video(_ sender: Any) { if (UIImage. Picker. Controller. is. Source. Type. Available(. photo. Library)) { flag. Image. Save = false image. Picker. delegate = self image. Picker. source. Type =. photo. Library image. Picker. media. Types = [k. UTType. Movie as String] image. Picker. allows. Editing = false present(image. Picker, animated: true, completion: nil) } else { let msg. Alert = UIAlert. Controller(title: "카메라", message: "카메라를 사용할 수 없음", preferred. Style: . alert) msg. Alert. add. Action(UIAlert. Action(title: "확인", style: . default)) present(msg. Alert, animated: true) } }

카메라 v View. Controller의 extension의 UIImage. Picker. Controller. Delegate 메소드 수정 // 이미지 피커에서

카메라 v View. Controller의 extension의 UIImage. Picker. Controller. Delegate 메소드 수정 // 이미지 피커에서 이미지를 선택했을 때 호출되는 메소드 func image. Picker. Controller(_ picker: UIImage. Picker. Controller, did. Finish. Picking. Media. With. Info info: [UIImage. Picker. Controller. Info. Key : Any]){ let media. Type = info[UIImage. Picker. Controller. Info. Key. media. Type] as! NSString if media. Type. is. Equal(to: k. UTType. Image as NSString as String) { capture. Image = info[UIImage. Picker. Controller. Info. Key. original. Image] as! UIImage if flag. Image. Save { UIImage. Write. To. Saved. Photos. Album(capture. Image, self, nil) } img. View. image = capture. Image self. dismiss(animated: true, completion: nil) } else if media. Type. is. Equal(to: k. UTType. Movie as NSString as String) { if flag. Image. Save { video. URL = (info[UIImage. Picker. Controller. Info. Key. media. URL] as! URL) UISave. Video. At. Path. To. Saved. Photos. Album(video. URL. relative. Path, self, nil) } self. dismiss(animated: true, completion: nil) }

카메라 v View. Controller의 extension의 UIImage. Picker. Controller. Delegate 메소드 수정 else{ // 이미지

카메라 v View. Controller의 extension의 UIImage. Picker. Controller. Delegate 메소드 수정 else{ // 이미지 피커 컨트롤러 창 닫기 picker. dismiss(animated: false) { () in // 이미지를 이미지 뷰에 표시 let img = info[UIImage. Picker. Controller. Info. Key. edited. Image] as? UIImage self. img. View. image = img } } }

카메라 v Info. plist 파일에 각각의 데이터를 사용하는 문자열을 등록 <key>NSCamera. Usage. Description</key> <string>카메라

카메라 v Info. plist 파일에 각각의 데이터를 사용하는 문자열을 등록 <key>NSCamera. Usage. Description</key> <string>카메라 사용</string> <key>NSMicrophone. Usage. Description</key> <string>비디오 촬영</string> <key>NSPhoto. Library. Add. Usage. Description</key> <string>포토를 사용합니다</string>

extension

extension

extension v [File] – [New]– [Target]을 실행해서 Photo Editing Extension 추가 : My. Photo.

extension v [File] – [New]– [Target]을 실행해서 Photo Editing Extension 추가 : My. Photo. Ext v My. Photo. Ext를 선택하고 실행 한 후 실행될 앱에서 사진(photo) 앱을 선택

extension v 비디오도 편집하고자 하는 경우 info. plist 파일의 설정 수정 <dict> <key>NSExtension. Attributes</key>

extension v 비디오도 편집하고자 하는 경우 info. plist 파일의 설정 수정 <dict> <key>NSExtension. Attributes</key> <dict> <key>PHSupported. Media. Types</key> <array> <string>Video</string> <string>Image</string> </array> </dict> <key>NSExtension. Main. Storyboard</key> <string>Main. Interface</string> <key>NSExtension. Point. Identifier</key> <string>com. apple. photo-editing</string> </dict>

extension v 이미지 뷰에는 image. VIew 라는 변수와 연결 v 3개의 바버튼은 seletor에 sepia.

extension v 이미지 뷰에는 image. VIew 라는 변수와 연결 v 3개의 바버튼은 seletor에 sepia. Selected, mono. Selected, invert. Selected 라는 메소드를 연결 @IBOutlet weak var image. View: UIImage. View! @IBAction func sepia. Selected(_ sender: Any) { } @IBAction func mono. Selected(_ sender: Any) { } @IBAction func invert. Selected(_ sender: Any) { }

extension v Photo. Editing. View. Controller. swift 파일에 2개의 인스턴스 변수 선언 var displayed.

extension v Photo. Editing. View. Controller. swift 파일에 2개의 인스턴스 변수 선언 var displayed. Image: UIImage? var image. Orientation: Int 32?

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에 내용 추가 //데이터에 대한 정보를 가져오는 메소드 - 2번째 호출되는 메소드 func start. Content. Editing(with content. Editing. Input: PHContent. Editing. Input, placeholder. Image: UIImage) { input = content. Editing. Input if let input = input { displayed. Image = input. display. Size. Image image. Orientation = input. full. Size. Image. Orientation image. View. image = displayed. Image } }

extension v Photo. Editing. View. Controller. swift 파일에 2개의 인스턴스 변수 선언 var current.

extension v Photo. Editing. View. Controller. swift 파일에 2개의 인스턴스 변수 선언 var current. Filter = "CIColor. Invert"

extension v Photo. Editing. View. Controller. swift 파일에 필터를 적용하기 위한 메소드 생성 func

extension v Photo. Editing. View. Controller. swift 파일에 필터를 적용하기 위한 메소드 생성 func perform. Filter(_ input. Image: UIImage, orientation: Int 32? ) -> UIImage? { var result. Image: UIImage? var cimage: CIImage cimage = CIImage(image: input. Image)! if let orientation = orientation { cimage = cimage. oriented(for. Exif. Orientation: orientation) } if let filter = CIFilter(name: current. Filter) { filter. set. Defaults() filter. set. Value(cimage, for. Key: "input. Image")

extension v Photo. Editing. View. Controller. swift 파일에 필터를 적용하기 위한 메소드 생성 switch

extension v Photo. Editing. View. Controller. swift 파일에 필터를 적용하기 위한 메소드 생성 switch current. Filter { case "CISepia. Tone", "CIEdges": filter. set. Value(0. 8, for. Key: "input. Intensity") case "CIMotion. Blur": filter. set. Value(25. 00, for. Key: "input. Radius") filter. set. Value(0. 00, for. Key: "input. Angle") default: break } if let ci. Filtered. Image = filter. output. Image { let context = CIContext(options: nil) if let cg. Image = context. create. CGImage(ci. Filtered. Image, from: ci. Filtered. Image. extent) { result. Image = UIImage(cg. Image: cg. Image) } } } return result. Image }

extension v Photo. Editing. View. Controller. swift 파일의 Action 메소드 구현 @IBAction func sepia.

extension v Photo. Editing. View. Controller. swift 파일의 Action 메소드 구현 @IBAction func sepia. Selected(_ sender: Any) { current. Filter = "CISepia. Tone" if let image = displayed. Image { image. View. image = perform. Filter(image, orientation: nil) } } @IBAction func mono. Selected(_ sender: Any) { current. Filter = "CIPhoto. Effect. Mono" if let image = displayed. Image { image. View. image = perform. Filter(image, orientation: nil) } } @IBAction func invert. Selected(_ sender: Any) { current. Filter = "CIColor. Invert" if let image = displayed. Image { image. View. image = perform. Filter(image, orientation: nil) } }

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에 내용 추가 func finish. Content. Editing(completion. Handler: @escaping ((PHContent. Editing. Output? ) -> Void)) { // Update UI to reflect that editing has finished and output is being rendered. // Render and provide output on a background queue. Dispatch. Queue. global(). async { // Create editing output from the editing input. //let output = PHContent. Editing. Output(content. Editing. Input: self. input!)

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에 내용 추가 if let input = self. input { let output = PHContent. Editing. Output(content. Editing. Input: input) let url = self. input? . full. Size. Image. URL if let image. Url = url, let full. Image = UIImage(contents. Of. File: image. Url. path), let result. Image = self. perform. Filter(full. Image, orientation: self. image. Orientation) { if let rendered. JPEGData = result. Image. jpeg. Data(compression. Quality: 0. 9) { try! rendered. JPEGData. write(to: output. rendered. Content. URL) } let archived. Data = try! NSKeyed. Archiver. archived. Data(with. Root. Object: self. current. Filter, requiring. Secure. Coding: true) let adjustment. Data = PHAdjustment. Data(format. Identifier: "cyberadam. cafe 24. com", format. Version: "1. 0", data: archived. Data) output. adjustment. Data = adjustment. Data }

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에

extension v Photo. Editing. View. Controller. swift 파일에 만들어져 있는 메소드 중에서 아래 메소드에 내용 추가 completion. Handler(output) } } }

extension v 프로젝트에 Today Extension을 생성 – My. Location v 프로젝트를 빌드하고 실행

extension v 프로젝트에 Today Extension을 생성 – My. Location v 프로젝트를 빌드하고 실행

extension v Storyboard 파일을 열어서 기존 레이블을 제거하고 2개의 레이블 추가하고 변수를 생성(latitude. Label,

extension v Storyboard 파일을 열어서 기존 레이블을 제거하고 2개의 레이블 추가하고 변수를 생성(latitude. Label, longitude. Label) v Today. View. Controller. swift 파일에 Core. Location 프레임워크 import Core. Location v Today. View. Controller. swift 파일에 위치 정보 사용을 위한 2개의 인스턴스 변수 선언 var location. Manager: CLLocation. Manager = CLLocation. Manager() var current. Location: CLLocation?

extension v Today. View. Controller. swift 파일에 view. Did. Load 메소드에 위치 정보 초기화

extension v Today. View. Controller. swift 파일에 view. Did. Load 메소드에 위치 정보 초기화 코드를 추가 override func view. Did. Load() { super. view. Did. Load() location. Manager. desired. Accuracy = k. CLLocation. Accuracy. Best location. Manager. delegate = self location. Manager. request. Location() }

extension v Today. View. Controller. swift 파일에 위치 정보를 확인하고 레이블에 출력하는 사용자 정의

extension v Today. View. Controller. swift 파일에 위치 정보를 확인하고 레이블에 출력하는 사용자 정의 함수를 추가 func update. Widget() { if let location = current. Location { let latitude. Text = String(format: "Lat: %. 4 f", location. coordinate. latitude) let longitude. Text = String(format: "Lon: %. 4 f", location. coordinate. longitude) latitude. Label. text = latitude. Text longitude. Label. text = longitude. Text } }

extension v Today. View. Controller. swift 파일에 제공되는 메소드의 내용을 수정 func widget. Perform.

extension v Today. View. Controller. swift 파일에 제공되는 메소드의 내용을 수정 func widget. Perform. Update(completion. Handler: (@escaping (NCUpdate. Result) -> Void)) { update. Widget() completion. Handler(NCUpdate. Result. new. Data) } v Today. View. Controller. swift 파일에 뷰가 보여질 때 마다 호출되는 메소드 재정의 override func view. Will. Appear(_ animated: Bool) { update. Widget() }

extension v Today. View. Controller. swift 파일에 extension을 추가하고 CLLocation. Manager. Delegate 프로토콜의 메소드를

extension v Today. View. Controller. swift 파일에 extension을 추가하고 CLLocation. Manager. Delegate 프로토콜의 메소드를 구현 extension Today. View. Controller : CLLocation. Manager. Delegate{ func location. Manager(_ manager: CLLocation. Manager, did. Update. Locations locations: [CLLocation]) { current. Location = locations[0] } func location. Manager(_ manager: CLLocation. Manager, did. Fail. With. Error error: Error) { NSLog(error. localized. Description) } }

extension v 이전에 만들어진 앱 중 하나에 앱의 스킴을 설정 – Info. plist 파일에

extension v 이전에 만들어진 앱 중 하나에 앱의 스킴을 설정 – Info. plist 파일에 추가 <key>CFBundle. URLTypes</key> <array> <dict> <key>CFBundle. URLName</key> <string>kr. co. pk. Location. Use</string> <key>CFBundle. URLSchemes</key> <array> <string>location</string> </array> </dict> </array>

extension v Extension 에 버튼을 1개 추가하고 touch. Up. Inside 이벤트에 메소드 연결(open. App)하고

extension v Extension 에 버튼을 1개 추가하고 touch. Up. Inside 이벤트에 메소드 연결(open. App)하고 코드 작성 @IBAction func open. App(_ sender: Any) { let url: URL? = URL(string: "location: ")! if let appurl = url { self. extension. Context!. open(appurl, completion. Handler: nil) } }