看板 KnucklesNote
作者 標題 [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.allowsEditing = false
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
設定選擇圖片的頁面不能編輯
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)
}
第一個函數在取得選取的圖片後,將選取的圖片做處理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)
}
}
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 累積人氣: 756
回列表(←)
分享