I am trying to parse data using AFNetworking & swift 3.0 and xcode 8.0 but i am getting error like below.below code works fine for swift 2.3 but not working in 3.0
Or if is there anyone know about AFNetworking & swift 3.0 using xcode 8.0 for POST & GET request please tell me. with simple example.
Thanks in Advance
You can see below error.
func callApi(apiName: String, param: [String : AnyObject]?, data: NSDictionary?, withMethod type: String, CompletionHandler:#escaping (_ code: Int, _ error:NSError?, _ response:AnyObject?) -> Void)
{
MBProgressHUD.showAdded(to: AppDelegateObj.window, animated: true)
let str_URL : String = kHOSTPATH+apiName
let manager: AFHTTPSessionManager = AFHTTPSessionManager()
if (type == kREQ_POST) {
manager.POST(str_URL, parameters: param, constructingBodyWithBlock: { (formData: AFMultipartFormData!) in
if data?.allValues.count != 0 && data != nil
{
let fileUrl = NSURL(fileURLWithPath: (data?.valueForKey("filePath"))! as! String)
try! formData.appendPartWithFileURL(fileUrl, name: (data?.valueForKey("key"))! as! String)
}
}, progress: { (NSProgress) in
}, success: { (task:URLSessionDataTask, responseObject) -> Void in
CompletionHandler(code: 1, error: nil, response:responseObject)
MBProgressHUD.hideHUDForView(AppDelegateObj.window, animated: true)
}, failure: { (task:URLSessionDataTask?, error:NSError) -> Void in
CompletionHandler(code: 0, error: error, response:nil)
MBProgressHUD.hideHUDForView(AppDelegateObj.window, animated: true)
})
}
else {
manager.GET(str_URL, parameters: param, progress: { (NSProgress) in
}, success: { (task:URLSessionDataTask, responseObject) -> Void in
CompletionHandler(code: 1, error: nil, response:responseObject)
MBProgressHUD.hideHUDForView(AppDelegateObj.window, animated: true)
}, failure: { (task:URLSessionDataTask?, error:NSError) -> Void in
CompletionHandler(code: 0, error: error, response:nil)
MBProgressHUD.hideHUDForView(AppDelegateObj.window, animated: true)
})
}
}
but i am getting error like this
cannot convert the value of type (URLSessionDataTask?,NSError)->Void to expected argument type '((URLSessionDataTask?,NSError)->Void)?'
Change your error type from NSERROR to ERROR. Type compatibility changed from Swift2.3 to Swift 3.0
Try this:
func Get()
{
let url = NSURL(string: Webserive.UserProfileInfoList + "/" + String(300))
let request = NSURLRequest(url: url! as URL)
NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: OperationQueue.main) {(response, data, error) in
self.GetData(data: data! as NSData)
}
}
func GetData(data:NSData){
let dict: NSDictionary!=(try! JSONSerialization.jsonObject(with: data as Data, options: JSONSerialization.ReadingOptions.mutableContainers)) as! NSDictionary
print(dict)
self.PostData()
}
func PostData(){
let parameters : NSMutableDictionary? = [
"UserID": String(300),
"UserProfileID": String(356)]
let manager = AFHTTPSessionManager()
let serializerRequest = AFJSONRequestSerializer()
serializerRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
manager.requestSerializer = serializerRequest
let serializerResponse = AFJSONResponseSerializer()
serializerResponse.readingOptions = JSONSerialization.ReadingOptions.allowFragments
serializerResponse.acceptableContentTypes = ((((NSSet(object: "application/json") as! Set<String>) as Set<String>) as Set<String>) as Set<String>) as Set<String>;
manager.responseSerializer = serializerResponse
manager.post(Webserive.DefaultProfile, parameters: parameters, progress: nil, success: { (task: URLSessionDataTask, responseObject: Any?) in
if (responseObject as? [String: AnyObject]) != nil {
print("responseObject \(responseObject)")
}
}) { (task: URLSessionDataTask?, error: Error) in
print("POST fails with error \(error)")
}
}
I had similar issue. Do not know what is the root of the problem but you can help yourself by not specifying some parameter's type, in this case 'error' in POST method call:
manager.post("http://...", parameters: [:], progress: nil, success: { (operation: URLSessionDataTask, responseObject: Any?) in
print("Success")
}, failure: { (operation: URLSessionDataTask?, error) in
let error = error as? Error
print("Failure, error is \(error?.description)")
})
With this code pattern I can build the code with Xcode 8.3 and Swift 3.
EDIT:
If you have some problem with "Cannot convert value of type...", please check type that function expects.
My problem was that I had declaration of Error as CoreData one and AFNetworking certainly does not return that Error type.
class Error: NSManagedObject {
// Insert code here to add functionality to your managed object subclass
}
What I needed to change was:
(operation: URLSessionDataTask?, error: Error?)
to:
(operation: URLSessionDataTask?, error: Swift.Error?)
Related
I am writing an app for a Udacity portfolio project which would fetch photos from Flickr and display in a collectionView. When a button is pressed, it will refresh the photos in the collectionView. However I am unable to get new sets of photos despite the fact that the search parameters have different page number after every call. My code as follows:
func getPhotosURLFromFlickr(_ lat: AnyObject, lon: AnyObject, _ completionHandlerForGetPhotosURL: #escaping (_ imageURL: [String]?, _ error: NSError?) -> Void) {
taskForGetPagesFromFlickr(lat, lon: lon) { (parameters, error) in
if let error = error {
completionHandlerForGetPhotosURL(nil, error as NSError)
} else {
if let parameters = parameters {
print(parameters)
self.taskForGetPhotos(parameters, { (imageURLArray, error) in
if let error = error {
completionHandlerForGetPhotosURL(nil, error as NSError)
} else {
if let imageURLArray = imageURLArray {
completionHandlerForGetPhotosURL(imageURLArray, nil)
}
}
})
}
}
}
}
func taskForGetPagesFromFlickr(_ lat: AnyObject, lon: AnyObject, _ completionHandlerForGetPhotosURL: #escaping (_ parameters: [String: AnyObject]?, _ error: NSError?) -> Void) {
let parameters = [
Constants.ParametersKey.Method: Constants.Methods.PhotoSearch as AnyObject,
Constants.ParametersKey.FlickrAPIKey : Constants.APIInfo.APIKey as AnyObject,
Constants.ParametersKey.Format: Constants.ParametersValues.JSON as AnyObject,
Constants.ParametersKey.NoJSONCallback: Constants.ParametersValues.DisableJSONCallback as AnyObject,
Constants.ParametersKey.PerPage: Constants.ParametersValues.Fifteen as AnyObject,
Constants.ParametersKey.Extras: Constants.ParametersValues.MediumURL as AnyObject]
var parametersWithCoord = parameters
parametersWithCoord[Constants.ParametersKey.lat] = lat
parametersWithCoord[Constants.ParametersKey.lon] = lon
let url = flickrURLFromParameters(parametersWithCoord)
let request = NSMutableURLRequest(url: url)
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
if let error = error {
completionHandlerForGetPhotosURL(nil, error as NSError)
} else {
self.convertDataWithCompletionHandler(data!, completionHandlerForConvertData: { (results, error) in
if let error = error {
completionHandlerForGetPhotosURL(nil, error as NSError)
} else {
// print(results)
guard let photosDict = results?["photos"] as? [String: AnyObject] else {
let userInfo = [NSLocalizedDescriptionKey : "NoPhotosFound"]
completionHandlerForGetPhotosURL(nil, NSError(domain: "NoPhotosFound", code: 1, userInfo: userInfo))
return
}
guard let pages = photosDict[Constants.ParametersKey.Pages] as? Int else {
let userInfo = [NSLocalizedDescriptionKey : "NoPagesFound"]
completionHandlerForGetPhotosURL(nil, NSError(domain: "NoPagesFound", code: 1, userInfo: userInfo))
return
}
let randomPageIndex = Int(arc4random_uniform(UInt32(pages)))
var searchParameters = parametersWithCoord
searchParameters[Constants.ParametersKey.Page] = randomPageIndex as AnyObject?
print("Number of pages: \(pages)")
print("Random page index: \(randomPageIndex)")
completionHandlerForGetPhotosURL(searchParameters, nil)
}
})
}
}
task.resume()
}
func taskForGetPhotos(_ parameters: [String: AnyObject], _ completionHandlerForGetPhotosURL: #escaping (_ imageURL: [String]?, _ error: NSError?) -> Void) {
let url = flickrURLFromParameters(parameters)
let request = NSMutableURLRequest(url: url)
print(url)
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
if let error = error {
completionHandlerForGetPhotosURL(nil, error as NSError)
} else {
self.convertDataWithCompletionHandler(data!, completionHandlerForConvertData: { (results, error) in
if let error = error {
completionHandlerForGetPhotosURL(nil, error as NSError)
} else {
// print(results)
guard let photosDict = results?["photos"] as? [String: AnyObject] else {
let userInfo = [NSLocalizedDescriptionKey : "NoPhotosFound"]
completionHandlerForGetPhotosURL(nil, NSError(domain: "NoPhotosFound", code: 1, userInfo: userInfo))
return
}
guard let photosArray = photosDict["photo"] as? [[String: AnyObject]] else {
let userInfo = [NSLocalizedDescriptionKey : "NoPhotosArrayFound"]
completionHandlerForGetPhotosURL(nil, NSError(domain: "NoPhotosArray", code: 1, userInfo: userInfo))
return
}
var imageURLArray: [String] = []
if photosArray.count != 0 {
for pics in photosArray {
guard let imageURLString = pics[Constants.ParametersValues.MediumURL] as? String else {
print("NoImageURLString Found")
return
}
imageURLArray.append(imageURLString)
}
}
print("ImageURLArray : \(imageURLArray)")
completionHandlerForGetPhotosURL(imageURLArray, nil)
}
})
}
}
task.resume()
}
When my refresh button is tapped, the above set of networking code runs, and if I tap the button twice, my print statements are as such:
FETCHING NEW COLLECTION...
Number of items 0 Number of pages: 5712
Random page index: 490
https://api.flickr.com/services/rest?page=490&method=flickr.photos.search&format=json&lon=103.7940514843148&api_key=APIKEY&per_page=15&lat=1.411935988414726&extras=url_m&nojsoncallback=1
ImageURLArray :
["https://farm3.staticflickr.com/2059/32542810620_37312d07c9.jpg",
"https://farm3.staticflickr.com/2330/32102051403_46e30a5eec.jpg",
"https://farm3.staticflickr.com/2104/32529883860_17558a0acf.jpg",
"https://farm3.staticflickr.com/2595/32778162441_db4a98d3cd.jpg",
"https://farm3.staticflickr.com/2466/32087213853_257910d32d.jpg",
"https://farm3.staticflickr.com/2029/32891916665_2d2d177e71.jpg",
"https://farm4.staticflickr.com/3685/32878992915_38baaf513e.jpg",
"https://farm1.staticflickr.com/631/32062787803_ed58defea5.jpg",
"https://farm3.staticflickr.com/2332/32873171215_c807db5364.jpg",
"https://farm3.staticflickr.com/2788/32825584606_7d2bff507c.jpg",
"https://farm3.staticflickr.com/2479/32052120503_1317f70f1a.jpg",
"https://farm3.staticflickr.com/2909/32023922664_d276f52369.jpg",
"https://farm1.staticflickr.com/376/32023912434_9b89fc3d7b.jpg",
"https://farm1.staticflickr.com/455/32018845514_22681384ae.jpg",
"https://farm3.staticflickr.com/2833/32734093131_0e8da333f4.jpg"]
FETCHING NEW COLLECTION...
Number of items 0 Number of pages: 5712
Random page index: 5383
https://api.flickr.com/services/rest?page=5383&method=flickr.photos.search&format=json&lon=103.7940514843148&api_key=APIKEY&per_page=15&lat=1.411935988414726&extras=url_m&nojsoncallback=1
ImageURLArray :
["https://farm3.staticflickr.com/2059/32542810620_37312d07c9.jpg",
"https://farm3.staticflickr.com/2330/32102051403_46e30a5eec.jpg",
"https://farm3.staticflickr.com/2104/32529883860_17558a0acf.jpg",
"https://farm3.staticflickr.com/2595/32778162441_db4a98d3cd.jpg",
"https://farm3.staticflickr.com/2466/32087213853_257910d32d.jpg",
"https://farm3.staticflickr.com/2029/32891916665_2d2d177e71.jpg",
"https://farm4.staticflickr.com/3685/32878992915_38baaf513e.jpg",
"https://farm1.staticflickr.com/631/32062787803_ed58defea5.jpg",
"https://farm3.staticflickr.com/2332/32873171215_c807db5364.jpg",
"https://farm3.staticflickr.com/2788/32825584606_7d2bff507c.jpg",
"https://farm3.staticflickr.com/2479/32052120503_1317f70f1a.jpg",
"https://farm3.staticflickr.com/2909/32023922664_d276f52369.jpg",
"https://farm1.staticflickr.com/376/32023912434_9b89fc3d7b.jpg",
"https://farm1.staticflickr.com/455/32018845514_22681384ae.jpg",
"https://farm3.staticflickr.com/2833/32734093131_0e8da333f4.jpg"]
You would realise that despite that the search page is different for both times, but the imageURLArray is actually the same. I can't seem to identify the reason why.
Some help is much appreciated pls, thanks!
Somehow I manage to solve my problem. I limit the randomPageIndex with a maximum number of 100 and it successfully refreshes the page.
Perhaps Flickr has some maximum search pages which I may not be aware of.
I am trying to extract a post request so it can be re-used and keep my code as DRY as possible bu I'm struggling a little. I started off with:
func createAccount() {
let manager = AFHTTPSessionManager()
let dob = self.dobTextField.text!.components(separatedBy: "/")
let URL = "https://splitterstripeservertest.herokuapp.com/account"
let params = [
"first_name": firstNameTextField.text!.trim(),
"last_name": lastNameTextField.text!.trim(),
"line1": addressLine1TextField.text!.trim(),
"city": cityTextField.text!.trim(),
"postal_code": postCodeTextField.text!.trim(),
"email": emailTextField.text!.trim(),
"day": UInt(dob[0])! as UInt,
"month": UInt(dob[1])! as UInt,
"year": UInt(dob[2])! as UInt] as [String : Any]
manager.requestSerializer = AFHTTPRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.post(URL, parameters: params, progress: nil, success: {(_ task: URLSessionDataTask, _ responseObject: Any) -> Void in
do {
let response = try JSONSerialization.jsonObject(with: responseObject as! Data, options: .mutableContainers) as? [String: Any]
self.stripeAccountID = response?["id"] as! String
self.stopAnimating()
self.goToFinalStage()
} catch {
print("Serialising new account json object went wrong.")
self.stopAnimating()
}
}, failure: { (operation, error) -> Void in
self.handleError(error as NSError)
self.stopAnimating()
})
}
and have it down to:
func createAccount() {
let request = HttpRequest()
let response = request.post(params: setParams(), URLExtension: "account")
if (response != nil) {
successfulRequest(response: response!)
} else {
failedRequest(response: response!)
}
}
func successfulRequest(response: AnyObject) {
self.stripeAccountID = response["id"] as! String
createMainBillSplitter()
self.stopAnimating()
performSegue(withIdentifier: "segueToFinalRegistrationViewController", sender: self)
}
func failedRequest(response: AnyObject) {
self.stopAnimating()
self.handleError(response["failed"] as! NSError)
}
where HTTPRequest is:
class HttpRequest {
let manager = AFHTTPSessionManager()
let baseURL = "https://splitterstripeservertest.herokuapp.com/account"
func post(params: [String: Any], URLExtension: String) -> AnyObject? {
let URL = baseURL + URLExtension
var response = [String: Any]()
manager.requestSerializer = AFHTTPRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.post(URL, parameters: params, progress: nil, success: {(_ task: URLSessionDataTask, _ responseObject: Any) -> Void in
do {
response = try JSONSerialization.jsonObject(with: responseObject as! Data, options: .mutableContainers) as! [String: Any]
} catch {
print("Serialising new account json object went wrong.")
}
}, failure: { (operation, error) -> Void in
response = ["failed": error]
})
return response as AnyObject?
}
func handleError(_ error: NSError) -> UIAlertController {
let alert = UIAlertController(title: "Please Try Again", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
return alert
}
}
But, I'm getting errors because the response is nil, which I'm sure is because there aren't completion handlers. I just don't understand enough how to implement them in this situation, so would really appreciate a push in the right direction. Thanks in advance!
You are getting confused with sync vs async operations.
The manager.post function will create your http request and will call the success closure when it is done. But since that function is implemented as an async operation, your code will not stop while that http request is being executed. So, your code will continue to be executed, and in your case, the very next line is you returning the response that is basically your empty array of Strings.
func post(params: [String: Any], URLExtension: String) -> AnyObject? {
let URL = baseURL + URLExtension
var response = [String: Any]()
manager.requestSerializer = AFHTTPRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.post(URL, parameters: params, progress: nil, success: {(_ task: URLSessionDataTask, _ responseObject: Any) -> Void in
// this closure is executed only when the request is completed
do {
response = try JSONSerialization.jsonObject(with: responseObject as! Data, options: .mutableContainers) as! [String: Any]
} catch {
print("Serialising new account json object went wrong.")
}
}, failure: { (operation, error) -> Void in
response = ["failed": error]
})
return response as AnyObject? // <<-- this line is executed right after the manager.post line above, but the success closure was not called yet because the request is still going on.
}
So, what you need to do is to not return the response right after the manager.post was called, but return it from inside the success closure. But you cannot simply use a return response statement. You need to pass the response as a parameter to a callback closure that you would pass to your request.post function.
Something like this:
func createAccount() {
let request = HttpRequest()
let response = request.post(params: setParams(),
URLExtension: "account",
success: {response in
// enter here the code to be executed when request is completed.
successfulRequest(response: response)
},
fail: {response in
failedRequest(response: response)
},)
}
and your class HttpRequest post function would be:
func post(params: [String: Any], URLExtension: String, success:([String: Any] -> Void), fail:([String: Any] -> Void)) -> AnyObject? {
let URL = baseURL + URLExtension
manager.requestSerializer = AFHTTPRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.post(URL, parameters: params, progress: nil, success: {(_ task: URLSessionDataTask, _ responseObject: Any) -> Void in
do {
response = try JSONSerialization.jsonObject(with: responseObject as! Data, options: .mutableContainers) as! [String: Any]
success(response)
} catch {
print("Serialising new account json object went wrong.")
}
}, failure: { (operation, error) -> Void in
response = ["failed": error]
fail(response)
})
}
PS: your code is assuming that it will always be able to decode the JSON response. Although you are using do / catch, if for some reason the JSON decoding fails, no response is being send back to your calling function. So, the app will just be stuck. I suggest you calling the fail() callback inside your catch block.
I am using AFNetworking with Swift 3.0 and I am stuck on one code.
func getJSON()
{
let manager = AFHTTPSessionManager()
manager.get(
url,
parameters: nil,
success:
{
(operation: URLSessionTask!, responseObject: Any?) in
print("JSON: " + responseObject!.description)
self.matchesArray = responseObject!.object(forKey: "matches")! as? NSMutableArray
self.tollBothPlazaTableView.reloadData()
},
failure:
{
(operation: URLSessionTask!, error: NSError) in
print("Error: " + error.localizedDescription)
}
)
}
It shows error on failure block.
Cannot convert value of type '(URLSessionTask!, NSError) -> ()' to expected argument type '((URLSessionDataTask?, Error) -> Void)?'`
Can someone explain what is wrong in my code. Also the correct way to use closures? (I am new to swift).
Error is clearly saying that use Error instead of NSError, in Swift 3 you need to use Error instead of NSError. So change your code like below.
func getJSON() {
let manager = AFHTTPSessionManager()
manager.get(
url,
parameters: nil,
success:
{
(operation, responseObject) in
if let dic = responseObject as? [String: Any], let matches = dic["matches"] as? [[String: Any]] {
print(matches)
}
DispatchQueue.main.async {
self.tollBothPlazaTableView.reloadData()
}
},
failure:
{
(operation, error) in
print("Error: " + error.localizedDescription)
})
}
Note: Always perform UI changes on main thread when you are on background thread, so batter to reload your tableView on main thread like I have done, Also use Swift native Array and Dictionary instead of NSArray and NSDictionary.
**Its Better to use Alamofire(same developer) in swift 3 **
func jsonRequest()
{
let url = "url"
//if you want to add paramter
parametr = ["username" : "user" , "password"]
Alamofire.request(url, method: .post, parameters: nil, encoding: JSONEncoding.default)
.responseJSON { response in
// print(response)
//to get status code
if let status = response.response?.statusCode {
switch(status){
case 201:
print("example success")
default:
print("error with response status: \(status)")
}
}
//to get JSON return value
if let array = response.result.value as? //NSDictionary [[String : Any]]
{
}
}
}
Since upgrading on Xcode 8 (Beta 1) and Swift 3 I have an error in this line:
account.requestAccessToAccounts(with: accountType, options: nil, completion: {(success: Bool, error: NSError!) -> Void in
It says:
Cannot convert value of type '(Bool, NSError!) -> Void' to expected argument type 'ACAccountStoreRequestAccessCompletionHandler!'
Before that line, I defined "account" and "accountType":
let account = ACAccountStore()
let accountType = account.accountType(
withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)
This is my (with Xcode 7 and Swift 2 working) code:
func getTimeline() {
//https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=2
let account = ACAccountStore()
let accountType = account.accountType(
withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)
account.requestAccessToAccounts(with: accountType, options: nil,
completion: {(success: Bool, error: NSError!) -> Void in
if success {
let arrayOfAccounts =
account.accounts(with: accountType)
if arrayOfAccounts.count > 0 {
let twitterAccount = arrayOfAccounts.last as! ACAccount
let requestURL = URL(string:
"https://api.twitter.com/1.1/statuses/user_timeline.json")
let parameters = ["screen_name": self.userName!,
"count" : "20"]
let postRequest = SLRequest(forServiceType:
SLServiceTypeTwitter,
requestMethod: SLRequestMethod.GET,
url: requestURL,
parameters: parameters)
postRequest.account = twitterAccount
postRequest.perform(
handler: {(responseData: Data!,
urlResponse: HTTPURLResponse!,
error: NSError!) -> Void in
if error != nil {
Crashlytics.sharedInstance().recordError(error)
}
do {
self.dataSource = try JSONSerialization.jsonObject(with: responseData, options: JSONSerialization.ReadingOptions.mutableLeaves) as! [AnyObject]
if self.dataSource.count != 0 {
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
} catch {
print("catching")
}
})
}
} else {
print("Failed to access account")
}
})
}
You should update your code as follows:
account.requestAccessToAccounts(with: accountType, options: [:]) {
(success: Bool, error: Error?) -> Void in
// blah blah: the rest of the code
}
This version is for Xcode 8 GM Swift3 (regular version)
In xcode 8.2 and swift 3 , I checked this method.
Remove Bool and NSError infront of success and error and it will be okey.
account.requestAccessToAccounts(with: accountType, options: nil,
completion: {(success, error) -> Void in
I hope it will help you, Good Luck :)
I am trying to send a multi-part post request which includes an image. The following code works fine:
manager.POST( apiUrl + "/location/add",
parameters: parameters,
constructingBodyWithBlock: { (formData : AFMultipartFormData!) -> Void in
// formData.appendPartWithFileURL(NSURL(string: location.imagePath!), name: "image", error: nil)},
formData.appendPartWithFileData(img, name: imgParam, fileName: "randomimagename.jpg", mimeType: "image/jpeg")},
success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in
println("JSON: " + responseObject.description)
var dict = responseObject as NSDictionary
let json = JSONValue(dict)
var message = ""
if let msg = json["message"].string {message = msg}
var success = false
if let s = json["success"].bool {
callback(success: success, msg: message)
}
},
failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
println("Error: " + error.localizedDescription)
var apiError = ApiError()
apiError.noConnection = true
errorCallback(apiError: apiError)
})
I want to use appendPartWithFileURL instead of appendPartWithFileData. If I replace the 5th line wiht the line which is commented out in the code above, I get the following compiler error:
Extra argument 'constructingBodyWithBlock' in call
Does anybody know how to resolve this?
edit: Found a (very, very, very strange) solution. Replace the line
formData.appendPartWithFileURL(NSURL(string: location.imagePath!), name: "image", error: nil)},
with
var temp = formData.appendPartWithFileURL(NSURL(string: location.imagePath!), name: "image", error: nil)},
I didn't change anything beside adding var temp =. I have no idea why this is working, but it does. Seems to be a strange bug.
If you haven't solved this problem yet, try casting location.imagePath to String.
I had the same problem till I've added as String in the following code:
func uploadFile(file: NSData, url: String, formData: NSDictionary, parameters: NSDictionary, completion: AnyObject -> Void, failure: NSError -> Void) {
operationManager.requestSerializer = AFJSONRequestSerializer() as AFHTTPRequestSerializer
if operationManager.reachabilityManager.networkReachabilityStatus != .NotReachable {
operationManager.POST(url, parameters: parameters, constructingBodyWithBlock: { (data) in
data.appendPartWithFileData(file, name: formData["fileName"] as String, fileName: formData["fileName"] as String, mimeType: formData["mimeType"] as String)
}, success: { (operation, responseObject) in
completion(responseObject)
}, failure: { (operation, error) in
failure(error)
})
} else {
showReachabilityAlert()
}
}
Hope it helps.
I kept receiving this error until I cast the URL as a string. Here's what I was doing (and receiving the error while doing so):
let manager = AFHTTPSessionManager()
let fullUrl = NSURL(string: name, relativeToURL: NSURL(string: apiBaseEndpoint))
manager.POST(fullUrl, parameters: nil, constructingBodyWithBlock: { (formData) in
formData.appendPartWithFormData(file, name: "image")
}, success: { (operation, responseObject) in
NSLog("hit success")
}, failure: { (operation, error) in
NSLog("hit the error")
})
To resolve the issue, I simply changed the assignment of fullUrl to take a string rather than NSURL by adding .absoluteString.
let fullUrl = NSURL(string: name, relativeToURL: NSURL(string: apiBaseEndpoint)).absoluteString