iOS Swift + Alamofire 上传带exif数据的照片

iOS Swift + Alamofire upload photos with exif data

我正在使用 Alamofire to upload multiple files at the same time to Open Asset using their REST API 并且我能够让它工作,但是,大部分 EXIF 数据都被删除了。不幸的是,EXIF 数据是必须的,因为我们需要能够通过各种 Web 客户端挖掘出 GPS 标签和其他一些东西。

经过一些研究,我发现问题是因为我正在使用 UIImageJPEGRepresentation 将照片转换为 NSData(这是 Alamofire 所期望的或文件 URL,它我不认为对我有用?)。

我也在使用 BSImagePicker library to allow the user to take/select multiple photos, which returns a an array of PHAsset,然后将其转换为 NSData。这是我执行此操作的函数(其中 collectedImages 是全局字典):

func compressPhotos(assets: [PHAsset]) -> Void {
        for asset in assets {
            let filename = self.getOriginalFilename(asset)
            let assetImage = self.getAssetPhoto(asset)

            let compressedImage = UIImageJPEGRepresentation(assetImage, 0.5)!  // bye bye metadata :(
            collectedImages[filename] = compressedImage
            print("compressed image: \(filename)")
        }
    }

如果我可以使用从 PHAsset 到 phone 本地图像的完整路径,我想我可以保留 EXIF 数据,但 Alamofire 似乎不支持那。我希望我错了。这是我的上传者:

func uploadPhotos(projectId: String, categoryId: String, data: [String: NSData], completionHandler: (AnyObject?, NSError?) -> ()) {
        var jsonBody = [AnyObject]()  //lazy
        Alamofire.upload(
            .POST,
            self.url + "/Files",
            multipartFormData: { multipartFormData in
                for (filename, img) in data {
                    jsonBody.append(["project_id": projectId, "category_id": categoryId, "original_filename": filename])
                    multipartFormData.appendBodyPart(data: img, name: "file", fileName: filename, mimeType: "image/jpeg")
                    print("img size: \(img.length)")

                }
                let jsonData = jsonToNSData(jsonBody)
                print("_jsonBody: \(jsonBody)")
                multipartFormData.appendBodyPart(data: jsonData!, name: "_jsonBody")
                print("multipart: \(multipartFormData)")
            },
            encodingCompletion: { encodingResult in
                switch encodingResult {
                case .Success(let upload, _, _):
                    upload.responseJSON { response in
                        debugPrint(response)
                        switch response.result {
                        case .Success(let value):
                            completionHandler(value as? NSArray, nil)
                        case .Failure(let error):
                            completionHandler(nil, error)
                        }

                    }
                case .Failure(let encodingError):
                    print(encodingError)
                }
            }
        )
    }

所以我的问题是,如何在保留所有 EXIF 数据的同时上传多张照片(同时也传递其他参数)? Alamofire 是一个很棒的库,我想在这里使用它,但如果我不能保留 EXIF 数据,我不会在上传过程中使用它。

我认为您可以先从 PHAsset 中获取文件 URL,然后在调用 multipartFormData.appendBodyPart(...) 时使用该文件 URL。像这样:

  1. 从 PHAsset 获取 URL:

    [asset requestContentEditingInputWithOptions:editOptions
                           completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
    NSURL *imageURL = contentEditingInput.fullSizeImageURL;
    }];
    
  2. 在 AlamoFire API 中使用文件 URL:

    multipartFormData.appendBodyPart(fileURL: imageURL, name: "image")

我不确定为什么 fullSizeImageURL 有问题,但它确实引导我走上了正确的道路,因为我能够通过将图像设为 NSData 来实现它] 从这样的文件路径:

asset.requestContentEditingInputWithOptions(PHContentEditingInputRequestOptions()) { (input, _) in
    let fileURL = input!.fullSizeImageURL?.filePathURL
    let data = NSData(contentsOfFile: fileURL!.path!)!

然后我只是在 Alamofire.request() 中将其作为 data 参数传递。这保留了所有原始照片元数据。