Moya / Moya

Network abstraction layer written in Swift.
https://moya.github.io
MIT License
15.09k stars 1.98k forks source link

How to upload image and/or image array as a multipart parameters ? #598

Closed swabzz closed 7 years ago

swabzz commented 8 years ago

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

BasThomas commented 8 years ago

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

leoneparise commented 8 years ago

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.

swabzz commented 8 years ago

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
swabzz commented 8 years ago
screen shot 2016-09-04 at 1 17 16 pm
leoneparise commented 8 years ago

.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
        }
    }
}
swabzz commented 8 years ago

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

BasThomas commented 8 years ago

What version of Moya are you using?

swabzz commented 8 years ago

Installing Moya using pod command

pod 'Moya'

I hope it installing latest version of Moya

BasThomas commented 8 years ago

Yeah, that installs the latest version.

swabzz commented 8 years ago

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:

BasThomas commented 8 years ago

Yeah, the syntax for that is the following:

pod 'Moya', '~> 7.0.0'
ivanbruel commented 8 years ago

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

swabzz commented 8 years ago

Another error

[!] Unable to satisfy the following requirements:

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.

ivanbruel commented 8 years ago

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.

swabzz commented 8 years ago
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'
ivanbruel commented 8 years ago

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'
swabzz commented 8 years ago

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

One last question please

How to upload multiple images??

swabzz commented 8 years ago

Any solution for uploading multiple images??

leoneparise commented 7 years ago

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.

riksof-zzlalani commented 7 years ago

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

sunshinejr commented 7 years ago

@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 🐼

riksof-zzlalani commented 7 years ago

@sunshinejr exactly that was the issue,

Thankyou Sir

sunshinejr commented 7 years ago

@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.

Michael-Maher-BBN commented 5 years ago

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