iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
Mobile Development

iOS學習資源與筆記系列 第 13

Swift,Image upload,Post

  • 分享至 

  • xImage
  •  

記錄學習內容。
主要是看網路上的文章和影片,做些紀錄。
內容可能有錯誤。

教學來源:
Image upload example using urlsession in swift ios

整理
1 看一下multipart/form-data 的內容:
Example of multipart/form-data
簡單來講就是一段boundary 放一個東西
-----------------------------1111111111111111111111111111111111
.jpg
-----------------------------1111111111111111111111111111111111
sometext
-----------------------------1111111111111111111111111111111111

2
教學影片的方法是:
從相簿裡選一張圖片,顯示在imageView上,然後有個上傳檔案按鈕

先練一下 相簿裡選一張圖片的 SwiftUI
The Complete Guide for Integrating Camera and Photo Library in SwiftUI
SwiftUI: UIImagePickerController with UIViewControllerRepresentable

3
遇到一個問題,post成功,回傳200 ,但是content-length是0。
可以去看Apache伺服器 裡面的error檔案 ,發現是圖片檔案太大了。
所以再回去複習php 設定:
https://ithelp.ithome.com.tw/articles/10228794

4
來看一下能不能取得圖片的資訊,
像是:檔名、解析度、上層資料夾名稱、檔案大小。
檔案太大的話,可能還要降低解析度。

練習
Uiimage 的內容:
https://developer.apple.com/documentation/uikit/uiimage

var scale: CGFloat : The scale factor of the image.
Scale會是1.0

var size: CGSize : The logical dimensions, in points, for the image.
可以用 size.height 和size.width

size.height 會是 2848.0
size.width 會是 4288.0

好像沒看到 圖片名稱 之類的資訊,繼續查:
跟這個有關:
UIImagePickerController.InfoKey

接著看了:
How to get file name in UIImagePickerController with Asset library?

static let imageURL: UIImagePickerController.InfoKey
The URL of the image file.

參考swift4的解答,獲得圖片檔名了!
用這個,會獲得全部路徑:
File//////////123.jpg
再取最後一個123.jpg(lastPathComponent)就可以了!

之後再補圖片的metadata!

5
來看有沒有辦法 把圖片解析度降低,讓檔案變小:
參考:
https://stackoverflow.com/questions/42398288/how-to-reduce-size-of-the-image-in-swift-ios

之後把

UIImageJPEGRepresentation 改成image.jpegData
就可以了。

參考:
UIImageJPEGRepresentation has been replaced by instance method UIImage.jpegData(compressionQuality:)

6
目前遇到 filename cannot be empty
發現tmp name是空的,某個部分可能錯誤了。還不知為何。

7
要加這個才能拿圖片:
iOS 10 存取使用者私密資料都要加上 usage description

總結目前問題:
1 tmp name是空的,檔案傳失敗
2 圖片的metadata 還沒找到方法來取得

新增:

1 wireshark觀察post :

https://serverfault.com/questions/309515/how-to-make-wireshark-filter-post-requests-only
[Day 9] 繼續玩過濾指令
https://ithelp.ithome.com.tw/articles/10194564

http.request.method == "POST"

android 最後是用okhttp 的post 傳圖片:
之前紀錄的:
https://ithelp.ithome.com.tw/articles/10228794
https://ithelp.ithome.com.tw/articles/10228840

requestBody.addFormDataPart(
    "fileUpload${i}", sourceFile.getName(),
    sourceFile.asRequestBody(media_type)
)

長這樣:

Encapsulated multipart part:  (image/jpeg)
Content-Disposition: from-data; name="postparam"; filename="test.jpg"
Content-Type:IMAGE/JPEG
Content-Length:379065
JPEG File Interchange Format:
……

一般的資料只有這樣:

Content-Disposition: from-data; name="postparam" \r\n\r\n

要手動把東西加上去。

因為看到FileName cannot be empty 的錯誤 。
應該需要增加圖片檔名 , 所以增加 :filename=”test.jpg”

        requestData.append("\(lineBreak)--\(boundary)\r\n" .data(using: .utf8)!)
        requestData.append("content-disposition: form-data; name=\"fileName\" ; filename=\(檔案名稱變數) \(lineBreak + lineBreak)" .data(using: .utf8)!)
        requestData.append("\(request.fileName + lineBreak)" .data(using: .utf8)!)

確實這樣就成功了。

還有發現一件事:每次選內建的圖片,檔名好像是隨機的。

接著發生錯誤:

File to open stream: No such file or directory 。

錯在php的這行:

copy($_FILES['uploadFile']['tmp_name'], $file_path  )

可能是指找不到$file_path 路徑 ? 不過路徑沒錯 ,也複製不過去。

發現:lineBreak 是\r\n ,作者每次都用了兩個lineBreak 就是\r\n\r\n,但 不是錯在這邊。

猜測出錯的地方可能是:

        requestData.append("\(request.fileName + lineBreak)" .data(using: .utf8)!)

所以把每一個資料都去掉lineBreak 。

最後一項參數好像要加一個lineBreak ,其餘不用加lineBreak (不確定)

改完之後,似乎就正確了。(不確定)


上一篇
蘋果檔案系統 APFS
下一篇
翻牌遊戲教學
系列文
iOS學習資源與筆記28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言