Swift4 tip

Programming/Swift 2018.08.27 10:14 Posted by 파란크리스마스

출처

Dictionary to JSON

출처 : Convert Dictionary to JSON in Swift - Stack Overflow

        let jsonData = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)
        let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String
        print(jsonString)

화면전환, 파라미터 전달

출처 : Swift 화면 전환 기법: 뷰 컨트롤러, 내비게이션 컨트롤러, 세그웨이 : 네이버 블로그

    func native_video_recording(_ data : NSDictionary) { 
        let vcRecord = self.storyboard!.instantiateViewController(withIdentifier: "vcRecord") as! RecordController // 1
        vcRecord.setParamData(data) // 파라미터 전달
        vcRecord.modalTransitionStyle = UIModalTransitionStyle.crossDissolve // 2
        self.present(vcRecord, animated: true) // 3
    }

카메라 리소스 구하기

출처 : GitHub - parthibanios/custom-Video-Recording-Swift-3.0: Record video using AVCapture AVFoundation framework

    //MARK:- Setup Camera
    func setupSession() -> Bool {
        
        //captureSession.sessionPreset = AVCaptureSessionPresetHigh
        //1080
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
        
        // Setup Camera
        let camera = AVCaptureDevice.default(for: .video)
        do {
            let input = try AVCaptureDeviceInput(device: camera!)
            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
                activeInput = input
            }
        } catch {
            print("Error setting device video input: \(error)")
            return false
        }
        
        // Setup Microphone
        let microphone = AVCaptureDevice.default(for: .audio)
        do {
            let micInput = try AVCaptureDeviceInput(device: microphone!)
            if captureSession.canAddInput(micInput) {
                captureSession.addInput(micInput)//addInput(micInput)
            }
        } catch {
            print("Error setting device audio input: \(error)")
            return false
        }
        movieOutput.maxRecordedDuration = CMTimeMake(9, 1)
        
        // Movie output
        if captureSession.canAddOutput(movieOutput) {
            captureSession.addOutput(movieOutput)
        }
        
        return true
    }

도큐먼트 디렉토리 구하기 - UIFileSharingEnabled 설정의 Root 경로

출처 : Swift로 파일 다루기 :

Eth Developer's Lab

    //EDIT 1: I FORGOT THIS AT FIRST
    func getMp4PathURL() -> URL? {
        /*
        let directory = NSTemporaryDirectory() as NSString
        
        if directory != "" {
            let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
            return URL(fileURLWithPath: path)
        }
        return nil
        */
        
        // 도큐먼트 디렉토리 구하기 - UIFileSharingEnabled의 Root 경로
        guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil }
        let fileName = NSUUID().uuidString + ".mp4"
        let fileURL = documentsDirectory.appendingPathComponent(fileName)
        
        /*
        print(imageURL)
        do {
            let imageData = try Data(contentsOf: imageURL)
            return UIImage(data: imageData)
        } catch let err as NSError {
            print("이미지 로딩 에러 : \(err)")
        }
        */
        
        return fileURL
    }

Swift4 : Alamofire 프로젝트에 추가하기

출처 : [iOS / Swift4] Alamofire 사용하기 | ry4nkim

Podfile 파일 편집

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'project' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  project 'project.xcodeproj'

  # Pods for project
  pod 'Firebase/Core'
  pod 'Firebase/Messaging'
  pod 'Alamofire', '~> 4.7'

end

pod install

$ pod install
Analyzing dependencies
Downloading dependencies
Installing Alamofire (4.7.3)
Installing Firebase 5.4.0
Installing FirebaseAnalytics (5.0.1)
Using FirebaseCore (5.0.5)
Using FirebaseInstanceID (3.1.1)
Using FirebaseMessaging (3.0.3)
Using GoogleToolboxForMac (2.1.4)
Using Protobuf (3.6.0)
Installing nanopb (0.3.8)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 3 dependencies from the Podfile and 9 total pods installed.
 
[!] Automatically assigning platform `ios` with version `9.3` on target `project` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.

Alamofire 파일 업로드, 결과 JSON 파싱

출력 : swift3 - upload image to server using Alamofire - Stack Overflow, ios - How to parse JSON response from Alamofire API in Swift? - Stack Overflow

        Alamofire.upload(multipartFormData: { (multipartFormData) in
            /*
            for (key, value) in parameters {
                multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
            }
            */
            multipartFormData.append("\(jsonString)".data(using: String.Encoding.utf8)!, withName: "json_str")
            
            /*
            if let data = imageData{
                multipartFormData.append(data, withName: "image", fileName: "image.png", mimeType: "image/png")
            }
            */
            multipartFormData.append(mp4FileUrl, withName: "test.mp4")
            
        }, usingThreshold: UInt64.init(), to: self.upload_url, method: .post, headers: headers) { (result) in
            switch result{
            case .success(let upload, _, _):
                upload.responseJSON { response in
                    print("Succesfully uploaded")
                    if let err = response.error {
                        print(err)
                        onCompletion?(nil, err)
                        return
                    }
                    if let result = response.result.value {
                        let JSON = result as! NSDictionary
                        print(JSON)
                        onCompletion?(JSON, nil)
                    }
                }
            case .failure(let error):
                print("Error in upload: \(error.localizedDescription)")
                onCompletion?(nil, error)
            }
        }

Timer, String format

출처 : ios - Swift - Update/Refresh Label that Displays Time - Stack Overflow

    let movieOutput = AVCaptureMovieFileOutput()
    var durationTimer: Timer?

    //MARK:- Setup Camera
    func setupSession() -> Bool {
        
        //captureSession.sessionPreset = AVCaptureSessionPresetHigh
        //1080
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
        
        // Setup Camera
        // 생략
        // Setup Microphone
        // 생략
 
        // 녹화 시간 제한
        movieOutput.maxRecordedDuration = CMTimeMake(300, 1)
        
        return true
    }

    @IBAction func startRecording() {

        if movieOutput.isRecording == false {
        
// ... 생략 ...
            
            self.seconds = 0
            self.durationTimer = Timer(timeInterval: 1.0, target: self, selector: #selector(self.refreshDurationLabel), userInfo: nil, repeats: true)
            RunLoop.current.add(self.durationTimer!, forMode: RunLoopMode.commonModes)
            self.durationTimer?.fire()
        } else {
            self.durationTimer?.invalidate()
            self.durationTimer = nil
            self.seconds = 0
            //self.durationTxt.text = secondsToFormatTimeFull(second: 0)
            stopRecording()
        }
    }

    func secondsToFormatTimeFull(second: Int)->String {
        let sec : Int = second % 60
        let min : Int = second / 60
        return String(format : "%02d:%02d", min, sec)
    }

    @objc func refreshDurationLabel() {
        self.durationTxt.text = secondsToFormatTimeFull(second: self.seconds)
        seconds = seconds + 1
    }

연락처 조회, 선택, WebView 자바스크립트 호출(evaluateJavaScript)

출처 : ContactsUISample/ViewController.swift at master · koogawa/ContactsUISample · GitHub
[SWIFT] 주소록에 저장된 데이터 불러오기 - Things take time - 티스토리

import Contacts
import ContactsUI

class WebViewBase : UIViewController, CNContactPickerDelegate {

    func native_show_contacts() {
        let pickerViewController = CNContactPickerViewController()
        pickerViewController.delegate = self
        
        // Display only a person's phone, email, and postal address
        let displayedItems = [CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactPostalAddressesKey]
        pickerViewController.displayedPropertyKeys = displayedItems
        
        // Show the picker
        self.present(pickerViewController, animated: true, completion: nil)
    }

    // MARK: CNContactPickerDelegate methods
    // Called when a property of the contact has been selected by the user.
    func contactPicker(picker: CNContactPickerViewController, didSelectContactProperty contactProperty: CNContactProperty) {
        //
    }
    
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
        // You can fetch selected name and number in the following way
        
        // user name
        let userName:String = contact.givenName
        
        let name = contact.familyName + contact.givenName
        //print(name)
        
        var primaryPhoneNumberStr:String = ""
        
        if (!contact.phoneNumbers.isEmpty) {
            // user phone number
            let userPhoneNumbers:[CNLabeledValue<cnphonenumber>] = contact.phoneNumbers
            let firstPhoneNumber:CNPhoneNumber = userPhoneNumbers[0].value
            
            
            // user phone number string
            primaryPhoneNumberStr = firstPhoneNumber.stringValue
        }
        
        //print("phonenum = \(primaryPhoneNumberStr)")
        
        webView.evaluateJavaScript("setContract('\(name)', '\(primaryPhoneNumberStr)')")
    }
    
    // Called when the user taps Cancel.
    func contactPickerDidCancel(picker: CNContactPickerViewController) {
        //
    }
}