顯示廣告
隱藏 ✕
看板 KnucklesNote
作者 Knuckles (站長 那克斯)
標題 [Xcode][Swift3] 加上上傳圖片功能
時間 2017-05-07 Sun. 23:48:57


在編輯器加上一個加入圖片的按鈕
[圖]


使用自訂圖示的方法參考 [Xcode][Swift3] 加入Google提供的圖示 Material icons - KnucklesNote板 - Disp BBS

使用 Assistant Editor 加入點擊按鈕的 @IBAction
名稱輸入「addPhoto」


修改編輯器的類別程式檔 EditorViewController.swift

類別加上繼承 UIImagePickerControllerDelegate, UINavigationControllerDelegate
class EditorViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

新增成員變數
    let imagePicker = UIImagePickerController()
建立一個 UIImagePickerController 在成員變數
避免每次加入圖片時都要再建立一次


在 viewDidLoad() 裡加上
        imagePicker.delegate = self


修改 addPhoto() 為
    @IBAction func addPhoto(_ sender: Any) {
        imagePicker.allowsEditing = false
        imagePicker.sourceType = .photoLibrary

        present(imagePicker, animated: true, completion: nil)
    }
imagePicker.allowsEditing = false
設定選擇圖片的頁面不能編輯

imagePicker.sourceType = .photoLibrary
設定選擇圖片時使用手機的相簿


加上兩個 delegate 函數
    // MARK: - UIImagePickerControllerDelegate

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            // 上傳圖片的程式 uploadImage() 寫在後面
            uploadImage(pickedImage)
        }
        dismiss(animated: true, completion: nil)
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }
第一個函數在取得選取的圖片後,將選取的圖片做處理
使用 dismiss 退回編輯器

第二個函數在選取圖片時點了 Cancel 後
使用 dismiss 退回編輯器


從 iOS 10 開始,要讀取手機相簿必需先設定隱私權限
否則一讀取就會閃退,並出現錯誤訊息:
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

在專案設定的「Info」,點一下任意項目後面的✚
輸入「Privacy」,下面就會列出各種權限設定
選擇「Privacy  - Photo Library Usage Description」
[圖]


後面的 Value 輸入需要權限的理由「加入圖片需要讀取相簿的權限」
[圖]



執行看看,第一次點了加入圖片的按鈕時,會出現要求權限
[圖]


點了 OK 後,就可以在相簿選取圖片了
[圖]



使用 Imgur API 上傳圖片

先參考 [PHP] 使用 Imgur API 上傳圖片 - KnucklesNote板 - Disp BBS
取得 Imgur 的 Client ID 以及 Mashape Key

參考 [Xcode][Swift3] 使用 Alamofire 存取網站資料 - KnucklesNote板 - Disp BBS
安裝 Alamofire 以及 AlamofireImage

加上成員函數 uploadImage()
    func uploadImage(image: UIImage) {
        let urlString = "https://imgur-apiv3.p.mashape.com/3/image/"
        // 在下面兩行設定自己的 Client ID 以及 Mashape Key
        let authorization = "Client-ID \(my_client_ID)"
        let mashapeKey = "\(my_mashape_key)"

        let width = image.size.width * image.scale
        let height = image.size.height * image.scale
        //print("width: \(width), height: \(height), scale: \(image.scale)")

        // 圖片太大的話,將圖片縮小        
        var scaledWidth = width, scaledHeight = height
        if scaledWidth > 1200 { // 寬度大於1200的話,等比例縮小到寬度為1024
            scaledWidth = 1024.0
            scaledHeight = height * 1024.0 / width
        }

        // af_imageScaled 產生的寬高會乘以 deviceScale,所以設定的寬高要先除以 deviceScale
        let deviceScale = UIScreen.main.scale
        let size = CGSize(width: scaledWidth/deviceScale, height: scaledHeight/deviceScale)
        // 使用 AlamofireImage 提供的 af_imageScaled 來縮圖
        let scaledImage = image.af_imageScaled(to: size)

        // 將圖片轉為 base64 字串        
        let imageData = UIImagePNGRepresentation(scaledImage)!
        let imageBase64 = imageData.base64EncodedString()

        let headers: HTTPHeaders = ["Authorization": authorization, "X-Mashape-Key": mashapeKey]
        let parameters: Parameters = ["image": imageBase64]
        Alamofire.request(urlString, method: .post, parameters: parameters, headers: headers).responseJSON { response in
            guard response.result.isSuccess else {
                let errorMessage = response.result.error?.localizedDescription
                self.alert(message: errorMessage!)
                return
            }
            guard let JSON = response.result.value as? [String: Any] else {
                self.alert(message: "JSON formate error")
                return
            }
            guard let success = JSON["success"] as? Bool,
                let data = JSON["data"] as? [String: Any] else {
                self.alert(message: "JSON formate error")
                return
            }
            if !success {
                let message = data["error"] as? String ?? "error"
                self.alert(message: message)
                return
            }
            if let link = data["link"] as? String,
                let width = data["width"] as? Int,
                let height = data["height"] as? Int {
                let bbcode = "[img=\(width)x\(height)]\(link)[/img]\n"
                //print(bbcode)
                // 將圖片網址插入輸入框的程式 textViewInsert() 寫在下面
                self.textViewInsert(string: bbcode)
            }
        }
    }

    // 在 textView 游標點選的地方插入字串,沒有點選的話會加在最後面
    func textViewInsert(string: String) {
        if let range = textTextView.selectedTextRange {
            self.textTextView.replace(range, withText: string)
        }
    }


設定語系

在專案設定的「Info」,將「Localization native development region」
由「en」改為「Taiwan」
[圖]


這樣選擇圖片時就會顯示中文了
[圖]




參考
Choosing Images with UIImagePickerController in Swift

--
※ 作者: Knuckles 時間: 2017-05-07 23:48:57
※ 編輯: Knuckles 時間: 2017-07-19 18:09:30
※ 看板: KnucklesNote 文章推薦值: 1 目前人氣: 0 累積人氣: 740 
分享網址: 複製 已複製
( ̄︶ ̄)b thqq5566 說讚!
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇