Moya: How to upload image and/or image array as a multipart parameters ?

Created on 2 Sep 2016  路  24Comments  路  Source: Moya/Moya

I tried all possible solution to upload image with moya but cant get proper way to upload it to server.
i tried same with alamofire and it is working fine.

can you please help me to upload image or multipart data using moya please ?
your give demo project too complex to understand also cant find documentation for this in your documentation list.

Thanks in advance

question

All 24 comments

Maybe @leoneparise can help with this. And the Multipart still has to be documented (see #586)

I'm documenting this feature but for next version (8.0), which changed a lot from version 7.0. You can use my comment on this issue https://github.com/Moya/Moya/issues/572 to guide you implementation.

Hello leoneparise,

Thanks for quick reply.
Still i am stuck in uploading image to server using Moya.

Here is my code. Give me some solution please ..

enum SomeAPI {
  case ChangeProfileImage(guideid: String, profileImage: UIImage, remove_pic_id: String)
}

extension SomeAPI: TargetType {

  var path:String {
    switch self {
    case .ChangeProfileImage: return "/posts"
    }
  }

  var method: Moya.Method {
    switch self {
    case .ChangeProfileImage: return .POST
    }
  }

  var parameters: [String: AnyObject]? {
    switch self {
     case .ChangeProfileImage(let guideid, let remove_pic_id, _):
            let values = ["guide_id": guideid, "remove_pic_id": remove_pic_id]
            return values
    }
  }

  var multipartBody: [MultipartFormData]? {
        switch self {
        case .ChangeProfileImage(_, let profileImage, _):
            return [MultipartFormData(provider: .File(profileImage), name: "files", mimeType:"image/jpeg", fileName: "photo.jpg")]  //HERE IS ERRO: ARGUMENT PASSED TO CALL THAT TAKES NO ARGUMENTS
        default:
            return []
        }
    }
    }
  }
}
please help me to upload image. Thanks in advance

screen shot 2016-09-04 at 1 17 16 pm

.File can be used only with NSURL and .Data with NSData. You need to convert your UIImage to NSData to build the Multipart.

Try this:

var multipartBody: [MultipartFormData]? {
        switch self {
        case .ChangeProfileImage(_, let profileImage, _):
            guard let data = UIImageJPEGRepresentation(profileImage, 1.0) else { return nil }
            return [MultipartFormData(provider: .Data(data), name: "files", mimeType:"image/jpeg", fileName: "photo.jpg")] 
        default:
            return nil
        }
    }
}

Thanks for reply. i have implemented code you have given but i am still getting same error of argument passed to call that takes no arguments.

I am sorry i giving trouble to you but just stuck in that passing parameters things.

I have imported Alamofire to resolve undifined identifier error of "MultipartFormData"

My imports are as

import Moya
import RxSwift
import Moya_ObjectMapper
import ObjectMapper
import Alamofire

See the error below. Please correct me what i am missing??

screen shot 2016-09-06 at 12 46 44 pm

Thanks in advance

What version of Moya are you using?

Installing Moya using pod command

pod 'Moya'

I hope it installing latest version of Moya

Yeah, that installs the latest version.

I tried manually to install latest version like
pod 'Moya', '7.0.0'

but in that case is produce another error while installing pod like

[!] Unable to satisfy the following requirements:

  • Moya (= 7.0.0) required by Podfile
  • Moya (= 7.0.0) required by Podfile
  • Moya (~> 6.0.0) required by Moya-ObjectMapper/Core (1.1.2)

Yeah, the syntax for that is the following:

pod 'Moya', '~> 7.0.0'

You should update Moya-ObjectMapper to 1.3.1, as it supports Moya 7.0.

Another error

[!] Unable to satisfy the following requirements:

  • Moya-ObjectMapper/RxSwift (= 1.1.2) required by Podfile
  • Moya-ObjectMapper/RxSwift (= 1.1.2) required by Podfile

Specs satisfying the Moya-ObjectMapper/RxSwift (= 1.1.2) dependency were found, but they required a higher minimum deployment target.

Specs satisfying the Moya-ObjectMapper/RxSwift (= 1.1.2) dependency were found, but they required a higher minimum deployment target.

Can you copy-paste your Podfile? Seems like you should also update Moya-ObjectMapper/RxSwift to 1.3.1, but a Podfile would provide more info.

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'ALCameraViewController'

pod 'Google/SignIn'

pod 'FBSDKCoreKit'
pod 'FBSDKShareKit'
pod 'FBSDKLoginKit'

pod 'Locksmith'
pod 'LicensesViewController', '~> 0.5.0'
pod 'SwiftyTimer'
pod 'SwiftyJSON'
pod 'SwiftLocation', '~> 1.0'
pod 'SwiftyUserDefaults'
pod 'TPKeyboardAvoiding'
pod 'SDWebImage', '~> 3.7'
pod 'SnapKit', '~> 0.15.0'
pod 'R.swift'
pod 'RxCache', '~> 0.1.2'
pod 'OkDataSources'
pod 'OkDataSources/RxSwift'
pod 'SwiftGen'
pod 'Alamofire', '~> 3.1.0'

pod 'Google/CloudMessaging'
pod 'GoogleMaps'
pod 'GooglePlaces'

pod 'PKHUD'
pod 'Swinject', '~> 1.0'
pod 'RxSwift',    '~> 2.0'

pod 'ObjectMapper', '~> 1.1.0'
pod 'Moya', '~> 7.0.0'
pod 'Moya/RxSwift'

pod 'Moya-ObjectMapper', '1.3.1'
pod 'Moya-ObjectMapper/RxSwift', '~> 1.3'


Try running pod update with the following pod versions.

pod 'Moya', '~> 7.0.0'
pod 'Moya/RxSwift', '~> 7.0.0'

pod 'Moya-ObjectMapper', '1.3.1'
pod 'Moya-ObjectMapper/RxSwift', '1.3.1'

Awesome Guys!!
You are best. Its Working fine now, Thanks For helping me.

One last question please

How to upload multiple images??

Any solution for uploading multiple images??

multipartBody param is an array of NSData. You can return the array pointing to the same name form parameter. That will be parsed by the server as an image array.

Hi

I'm using Moya for handling communication between my swift application and api, I'm able to post and get data but unable to post file to api server, following is my code

enum TestApi {
  ...
  case PostTest(obj: [String: AnyObject])
  ...
}

extension TestApi: TargetType {

  var baseURL: NSURL {
    switch self {
    case .PostTest:
      return NSURL(string: "http://192.168.9.121:3000")!
    }
  }

  var path: String {
    switch self {
    case .PostTest:
      return "/api/file"
    }
  }

  var method: Moya.Method {
    switch self {
    case .PostTest:
      return .POST
    }
  }

  var parameters: [String: AnyObject]? {
    switch self {
    case .PostTest(let obj):
      return ["image": obj["image"]!]
    }
  }

  var sampleData: NSData {
    return "".dataUsingEncoding(NSUTF8StringEncoding)!
  }

  var multipartBody: [MultipartFormData]? {
    switch self {
    case .PostTest(let multipartData):

      guard let image = multipartData["image"] as? [NSData] else { return[] }

      let formData: [MultipartFormData] = image.map{MultipartFormData(provider: .Data($0), name: "images", mimeType: "image/jpeg", fileName: "photo.jpg")}
      return formData


    default:
      return []
    }
  }
}

and following is the way I called

return testApiProvider.request(.PostTest(obj: _file)).debug().mapJSON().map({ JSON -> EKResponse? in
  return Mapper<EKResponse>().map(JSON)
})

I dont receive no response and no hit was sent to the api server

@riksof-zzlalani Hey there! What your code is lacking is subscription. This is not _really_ a Moya problem, but problem with Reactive Extensions. So, a quick fix would be a following:

return testApiProvider
    .request(.PostTest(obj: _file))
    .debug()
    .mapJSON()
    .map({ JSON -> EKResponse? in
        return Mapper<EKResponse>().map(JSON)
    })
    .subscribeNext { _ in }

I hope it helps! Please next time use another issue for questions if they are touching quite different topic, so others can easily search for it 馃惣

@sunshinejr exactly that was the issue,

Thankyou Sir

@riksof-zzlalani no problem! I think that the original problem @swabzz had should be resolved as of now, so I'm gonna close for now.

@swabzz can you please provide me Task code for your provider file ??

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BasThomas picture BasThomas  路  31Comments

jonlambert picture jonlambert  路  31Comments

pete183 picture pete183  路  25Comments

iballan picture iballan  路  35Comments

Matthijn picture Matthijn  路  27Comments