【问题标题】:Alamofire error Code=-1000 "The URL does not point to a file URL"Alamofire 错误代码=-1000 “该 URL 未指向文件 URL”
【发布时间】:2015-11-28 17:18:35
【问题描述】:

从我正在开发的 iOS 应用程序将图像上传到我的服务器时遇到问题。我正在使用 Alamofire 和 UIImagePickerController

didFinishPickingMediaWithInfo 委托方法中,我将用户从info[UIImagePickerControllerReferenceURL] 选择的文件作为NSURL 保存在名为self.imageNSURL 的变量中。

将其传递给 Alamofires 上传 multipartFormData 方法(几乎是来自他们的 docs 的标准复制和粘贴)

Alamofire.upload(
    .POST,
    URLString: "http://app.staging.acme.com/api/users/\(id)/picture",
    multipartFormData: { multipartFormData in
        multipartFormData.appendBodyPart(fileURL: self.imageNSURL, name: "image")
    },
    encodingCompletion: { encodingResult in
        switch encodingResult {
        case .Success(let upload, _, _):
            upload.responseJSON { request, response, JSON, error in
                println(JSON)
            }
        case .Failure(let encodingError):
            println(encodingError)
        }
    }
)   

我得到的回报是

Error Domain=com.alamofire.error Code=-1000 "The operation couldn’t be completed. The URL does not point to a file URL: assets-library://asset/asset.JPG?id=00000000-0000-0000-0000-000000000000&ext=JPG" UserInfo=0x00000000000 {NSLocalizedFailureReason=The URL does not point to a file URL: assets-library://asset/asset.JPG?id=00000000-0000-0000-0000-000000000000&ext=JPG}

请注意,我在这篇文章的回复中削弱了 ID,实际的错误消息包含有效的。

【问题讨论】:

    标签: ios swift uiimagepickercontroller nsurl alamofire


    【解决方案1】:

    这是由于从info[UIImagePickerControllerReferenceURL] 返回的 URL,此 URL 指向 assets-library/asset,这是由于沙盒。因此,您无法使用此 URL 访问文件,这就是 alamofire 抱怨您的 URL 不是文件 URL 的原因。解决这个问题可以使用multipartFormData.appendBodyPart(data: data, name: name)这个方法把要发送的数据直接作为NSData。完整代码示例:

    let imagePicked = info[UIImagePickerControllerOriginalImage]
    let imageExtenstion = info[UIImagePickerControllerReferenceURL]
    // imageExtenstion will be "asset.JPG"/"asset.JPEG"/"asset.PNG"
    // so we have to remove the asset. part
    var imagePickedData : NSData
    switch imageExtenstion {
        case "PNG": imagePickedData = UIImagePNGRepresentation(imagePicked)!
       // compressionQuality is a float between 0.0 and 1.0 with 0.0 being most compressed with lower quality and 1.0 least compressed with higher quality
        case "JPG", "JPEG": imagePickedData = UIImageJPEGRepresentation(image, compressionQuality)!
    }
    Alamofire.upload(.POST, YOUR_URL, multipartFormData: { multipartFormData in 
         multipartFormData.appendBodyPart(data: imagePickedData, name: imageName)
     }, encodingCompletion: { encodingResult in
        switch encodingResult {
        case .Success(let upload, _, _):
            upload.responseJSON { request, response, JSON, error in
                print(JSON)
            }
        case .Failure(let encodingError):
            print(encodingError)
        }
    })
    

    【讨论】:

    • 嗨!有没有办法获得正确的路径?文档目录中文件的路径是否明确正确?
    【解决方案2】:

    我之前遇到过同样的问题。幸运的是,Alamofire 有办法避免将 .jpeg 文件显式上传到您的服务器,这是有益的,因为它避免了将图像 NSData 写入磁盘所需的时间。这是通过multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "image.jpeg", mimeType: "image/jpeg") 完成的。

    下面是一个更详细的例子:

    Alamofire.upload(.POST, "path/to/resource/to/receive/image/", multipartFormData: { multipartFormData -> Void in
            /**
            - parameter imageData: NSData representation of your image
            - parameter name: String of the name to associated with the data in the Content-Disposition HTTP header. To use an HTML example, "image" in the following code: <input type="file" name="image">
            - parameter fileName: String of the name that you are giving the image file, an example being image.jpeg
            - parameter mimeType: String of the type of file you are uploading (image/jpeg, image/png, etc)
            **/
            multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "image.jpeg", mimeType: "image/jpeg")
            }, encodingCompletion: { encodingResult in
                switch encodingResult {
                case .Success(let upload, _, _):
                    upload.responseJSON { response in
                        debugPrint(response)
                    }
                case .Failure(let encodingError):
                    print(encodingError)
                }
    })
    

    【讨论】:

      【解决方案3】:

      我在本地图像路径上遇到了同样的问题,通过设置正确的路径解决了

      实用功能

      var TimestampJPGImageName :String {
          var stringTimeStamp =  "\(NSDate().timeIntervalSince1970 * 1000)"
          stringTimeStamp = stringTimeStamp.stringByReplacingOccurrencesOfString(".", withString: "_")
          stringTimeStamp = stringTimeStamp.stringByAppendingString(".jpg")
          stringTimeStamp = stringTimeStamp.stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLQueryAllowedCharacterSet())!
      
          return stringTimeStamp
      }
      
      func fileUrlForPathComponent(pathComponent: String) -> NSURL?{
      
          let pathDocumentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
          let filePath = "\(pathDocumentDirectory)/\(pathComponent)"
          let fileUrl = NSURL(fileURLWithPath: filePath)
      
          return fileUrl
      }
      
      func fileSaveToDirectory(image: UIImage, name: String?) -> NSURL? {
      
          //let fileManager = NSFileManager.defaultManager()
          //fileManager.createFileAtPath(fileUrlToWrite!.path, contents: imageData, attributes: nil)
      
          var fileUrlToWrite : NSURL? = nil
          if let fileName : String = name {
              fileUrlToWrite = fileUrlForPathComponent(fileName)//.stringByAppendingString(".png")
          }else{
              fileUrlToWrite = fileUrlForPathComponent(TimestampJPGImageName)//.stringByAppendingString(".png")
          }
      
          assert(fileUrlToWrite != nil, "please check filePath")
          if (fileUrlToWrite != nil){
              let imageData: NSData = UIImageJPEGRepresentation(image, 0.6)!
      
              imageData.writeToFile(fileUrlToWrite!.path!, atomically: false)
      
              return fileUrlToWrite!
          }
          else{
              return nil
          }
      }
      
      func fileRemoveAtURL(URL : NSURL) ->(success : Bool?, message : String?){
      
          if let path : String = URL.path{
      
              let fileManager = NSFileManager.defaultManager()
      
              do {
                  try fileManager.removeItemAtPath(path)
              }
              catch let error as NSError {
                  return (false, error.localizedDescription)
              }
              return (true, "file removed!")
          }else{
              return (false, "invalid path!")
          }
      }
      

      提出请求

      func requestCreateEvent(){
      
          if (canMakeAPIRequest() == false){
              return
          }
      
          let imageJPEGname = TimestampJPGImageName
          var parameters : Dictionary<String, AnyObject> =
              ["event[eventName]" : configuration.stringEventName,
               "event[images][0][image][imageFile]" : self.imageTaken!,
               "event[images][0][image][imageName]" : imageJPEGname,
          ]
          var headers = [String:String]()
          headers["Content-Type"] = "multipart/form-data"
      
          let urlpath = URL_CreateEvent.stringByAppendingString("?access_token=\(gblConfiguration!.AppToken!.accessToken)")
      
          var arrayImageURL : Array<NSURL> = []
      
          self.view.showLoader()
          Alamofire.upload(.POST, urlpath, headers: headers, multipartFormData: { (multipartFormData) -> Void in
      
              if let dictUpload : Dictionary<String, AnyObject> = parameters {
      
                  for (key , value) in dictUpload {
      
                      if value.isKindOfClass(UIImage) {
      
                          if let image = value as? UIImage{
      
                              /*
                               //Upload Image with Data
      
                               if let imageData = UIImageJPEGRepresentation(image, 0.8) {
                                  multipartFormData.appendBodyPart(data: imageData, name: key, fileName: imageJPEGname, mimeType: "image/jpg")
                              }else if let imageData = UIImagePNGRepresentation(image) {
                                  multipartFormData.appendBodyPart(data: imageData, name: key, fileName: "myImage.png", mimeType: "image/png")
                              }*/
      
      
                              //Upload Image with URL PATH
                              if let fileURL : NSURL = fileSaveToDirectory(image, name: imageJPEGname)
                              {
                                  multipartFormData.appendBodyPart(fileURL: fileURL , name: key)
                                  arrayImageURL.append(fileURL)
                              }
                              else {
                                  assert(false, "Unable to save file-name \(imageJPEGname)")
                              }
                          }
                      }
                      else {
                          multipartFormData.appendBodyPart(data: "\(value)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name: key)
                      }
                  }
              }
      
              }, encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold, encodingCompletion:{
                  encodingResult in
      
                  switch encodingResult {
                  case .Success(let request, let _, let _):
      
                      request.responseJSON { response in
      
                          //debugPrint(response)
                          self.view.hideLoader()
      
                          if let objResponse : NSHTTPURLResponse = response.response {
      
                              if objResponse.statusCode == 201 { //SUCCESS STATUS
      
                                  for url : NSURL in arrayImageURL {
                                      fileRemoveAtURL(url)
                                  }
      
                                  let alert = UIAlertView.init(title: AppName, message: "Event Created!", delegate: nil
                                      , cancelButtonTitle: "OK")
                                  alert.show()
                                  self.navigationController?.popToRootViewControllerAnimated(true)
                              }
                              else if objResponse.statusCode == 500 {
                                  let alert = UIAlertView.init(title: AppName, message: "Bad access", delegate: nil
                                      , cancelButtonTitle: "OK")
                                  alert.show()
                              }
                          }
      
                          switch response.result {
                          case .Success(let JSON): // Error Handling
      
                              if let responseDictionary = JSON as? NSDictionary {
      
                                  if let errors = responseDictionary["errors"] {
      
                                      if let _ = errors["errors"] as? Array<String>
                                      {
                                          showErrorMessageAlertView(errors, viewdelegate: self)
                                      }
                                  }
                                  else if let error = responseDictionary["error"] as? String,
                                      let errorDescription = responseDictionary["error_description"] as? String
                                  {
                                      let alert = UIAlertView.init(title: error, message: errorDescription, delegate: nil
                                          , cancelButtonTitle: "OK")
                                      alert.show()
                                  }
                              }
                          case .Failure(let error):
                              print("Request failed with error: \(error)")
                          }
                      }
                      break
      
                  case .Failure(let encodingError as NSError):
                      print(encodingError)
                      self.view.hideLoader()
      
                      showErrorMessageAlertView(encodingError, viewdelegate: nil)
                      break
      
                  default :
                      self.view.hideLoader()
                      break
      
                  }
              }
          )
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-04
        • 2021-07-05
        • 1970-01-01
        • 1970-01-01
        • 2020-04-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多