EXC_BAD_ACCESS Error In App, Alamofire 3.1.2 - iphone

I'm running Xcode 7.1, with an iOS device on 9.1, and the latest version of Alamofire, I believe it's 3.1.2.
I've seen others with similar errors - this one from SO and this one from their Github issues page - to mine, but the resolutions did not work for me. The resolutions that worked in these scenarios seemed to be deleting the DerivedData folders, but that doesn't work in my situation.
The issue is that I can make web requests with Alamofire when I run in the simulator, but I get the following error (in the image) when I install the application on my device.
I've tried using a device running 9.1, 9.0.1 and 8.3. All of these devices crash when I attempt to make the web request. I'm stuck on this and I've made no headway. This worked until I updated all my pods in my podfile and my Xcode version a couple of nights ago.
I'm a newbie at iOS development, so if you need to see more error logs or things of that nature, let me know and I'll do my best to get you those. Any help is appreciated.
Edit: Adding code for the Alamofire.request method as requested. Also adding code for the referenced Manager.sharedInstance.request method. These are methods within the Alamofire library itself.
// Alamofire.request
public func request(
method: Method,
_ URLString: URLStringConvertible,
parameters: [String: AnyObject]? = nil,
encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil)
-> Request
{
return Manager.sharedInstance.request(
method,
URLString,
parameters: parameters,
encoding: encoding,
headers: headers
)
}
// Manager.sharedInstance.request
public func request(
method: Method,
_ URLString: URLStringConvertible,
parameters: [String: AnyObject]? = nil,
encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil)
-> Request
{
let mutableURLRequest = URLRequest(method, URLString, headers: headers)
let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0
return request(encodedURLRequest)
}

One problem is that stringByAddingPercentEncodingWithAllowedCharacters returns an optional, and when you do string interpolation, you're going to get Optional(...) appearing in the string. Thus when it tries to create a URL from that, it's undoubtedly failing. Print the uri string and you'll see the issue. E.g., if the searchTerm was "foo bar", the uri would become:
https://api.spotify.com/v1/search&q=Optional("foo%20bar")&type=artist,album,track
But that's not correct. Add a ! to the end of the expression to unwrap it:
let searchTermEncoded = searchTerm.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
And then the URI will be (largely) correct.
--
I'd suggest not doing this percent escaping yourself (as the character set you're using is not correct, even once you do properly unwrap searchTermEncoded). Let Alamofire do this for you:
let urlString = "https://api.spotify.com/v1/search"
let parameters = ["q" : searchTerm, "type" : "artist,album,track"]
Alamofire.request(.GET, urlString, parameters: parameters)
.responseJSON { response in
guard response.result.error == nil else {
print(response.result.error)
return
}
print(response.result.value)
}

Related

ParameterEncoder Problem Updating Alamofire from version 4 to 5

I am updating my project from Alamofire version 4 to 5. And I am running into a snag. I use to encode my parameters with the follow :
// This struct lets us keep the square brackets in the HTTP GET Request vars to keep the php arrays in tact for the backend
struct BracketGetEncoding: ParameterEncoding {
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try URLEncoding().encode(urlRequest, with: parameters)
request.url = URL(string: request.url!.absoluteString.replacingOccurrences(of: "%5B", with: "[").replacingOccurrences(of: "%5D", with: "]"))
return request
}
}
let request = AF.request(urlString, method: method, parameters: parameters, encoder: BracketGetEncoding(), headers: getRequestHeadersAsHTTPHeaders(), interceptor: nil, requestModifier: nil)
But I am trying to find the equivilant with the update. It now takes a ParameterEncoder instead of a ParameterEncoding.
There are two top level request methods: one that takes the new ParameterEncoder type, and one that takes the older ParameterEncoding type. You can use the old one by changing your encoder parameter to encoding.
I suggest you transition to the ParameterEncoder version when you can, as we're not sure if ParameterEncoding will be supported in the next major version of Alamofire.
Here is the update for people who are looking to do the same thing :
// This struct lets us keep the square brackets in the HTTP GET Request vars to keep the php arrays in tact for the backend
struct BracketParameterEncoder : ParameterEncoder {
func encode<Parameters>(_ parameters: Parameters?, into urlRequest: URLRequest) throws -> URLRequest where Parameters : Encodable {
var request = try URLEncodedFormParameterEncoder.default.encode(parameters, into: urlRequest)
request.url = URL(string: request.url!.absoluteString.replacingOccurrences(of: "%5B", with: "[").replacingOccurrences(of: "%5D", with: "]"))
return request
}
}

Alamofire 4 sends method as POST but server reads it GET

I have a very weird problem here, using Alamofire 4 Swift 4 Xcode 9.1
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 30
manager.session.configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
let request = manager.request(
url,
method: HTTPMethod.post,
parameters: [:])
But server replies with method not allowed because it reads it as GET, however, if I change HTTPMethod.put or .delete or any other method, the server reads it correctly, the problem is with post specifically!
By debugging Alamofire's class 'SessionManager', specially the following method:
open func request(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)
-> DataRequest
The method here is correct, POST, so it's just fine before it goes out the application, what's wrong?
It was adding '/' at the end of the URL that was causing this.

Alamofire with YouTube API Issues (Swift 3)

I'm having some trouble converting my old Alamofire code to the new Swift 3 version. I'm getting the error: Extra argument 'method' in call
// Fetch the videos dynamiclly through the YouTube Data API
Alamofire.request("https://www.googleapis.com/youtube/v3/playlistItems", method: .get, parameters: ["part":"snippet", "playlistId":UPLOADS_PLAYLIST_ID,"key":API_KEY], encoding: ParameterEncoding.URL, headers: nil)
Can someone help me with this?
The problem is not in the method argument but in the encoding which you can set to URLEncoding.default also since the header is nil then i guess you dont need it
let parameters: Parameters = ["part":"snippet",
"playlistId":UPLOADS_PLAYLIST_ID,
"key":API_KEY]
let url = "https://www.googleapis.com/youtube/v3/playlistItems"
Alamofire.request(url,
method: .get,
parameters: parameters,
encoding: URLEncoding.default)
.responseData(completionHandler: { response in
//do what you want
})
by the way you can change responseData back to what you already have

Issue with Alamofire Request

I am trying to use Alamofire to make a web request. It had been working absolutely fine, but after doing a recent pod update it has stopped.
My syntax is:
var params = [String : Any]()
if (data != nil) {
params = try! JSONSerialization.jsonObject(with: data!, options: []) as! [String : Any]
}
let _ = Alamofire.request( "http://example.com" , method: Method, parameters: params?, encoding: .queryString, headers: [:]).response{ (request, response, data, error) in
}
the error looks is "Extra argument 'method' in call" and I don't seem to be able to get rid of it. My parameters of the request to Alamofire.request seem ok to me, but clearly I am missing something.
You're not passing anything to the method parameter. I don't know what you're trying to provide in the encoding parameter either but that went through some changes in Alamofire 4.0. For example and for simplicity's sake, this compiles:
let _ = Alamofire.request( "http://example.com" , method: HTTPMethod.get, parameters: nil, encoding: JSONEncoding.default, headers: nil)

Alamofire download method "Use of undeclared type ´DownloadFileDestination´"

I´m trying to write the method to download a file with custom parameters and headers, but when I write the method XCode shows the Usage of undeclared type 'DownloadFileDestination'
Here's my code:
public func download(JSON jsonObject:[String:AnyObject], inUrl url:URLStringConvertible,headers:[String:String]?,paramEnconding:ParameterEncoding) {
let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)
Alamofire.download(method: Method, URLString: URLStringConvertible, parameters: [String: AnyObject]?, encoding: ParameterEncoding,headers: [String: String]?, destination: DownloadFileDestination) { temporaryURL, response in
let fileManager = NSFileManager.defaultManager()
let directoryURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let pathComponent = response.suggestedFilename
return directoryURL.URLByAppendingPathComponent(pathComponent!)
}
}
Note that I haven't put the markdown and still XCode throws the error.
You have code that calls download like so:
Alamofire.download(method: Method, URLString: URLStringConvertible, parameters: [String: AnyObject]?, encoding: ParameterEncoding,headers: [String: String]?, destination: DownloadFileDestination) { ... }
But all of those parameters, Method, URLStringConvertible, etc, including DownloadFileDestination are the types for those parameters. But you should be passing values (e.g. instances of objects of those respective types). Most of these parameters were provided as parameters to the method you're defining here, so you'd just use those. I only had to guess what you wanted regarding the http method.
Another curious thing in the code sample is that defined destination, calling the suggestedDownloadDestination method that builds the closure for you. But you then implemented your own closure. Do one or the other, but not both.
So, eliminating that redundant closure and using the parameters you passed to this method, you get something like:
func download(JSON jsonObject: [String: AnyObject], inUrl url: URLStringConvertible, headers: [String: String]?, paramEncoding: ParameterEncoding) {
let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)
Alamofire.download(.POST, url, parameters: jsonObject, encoding: paramEncoding, headers: headers, destination: destination)
}
I'm guessing you wanted .POST. Perhaps you wanted to use .GET (but, in that case, it wouldn't make sense to pass ParameterEncoding because some encodings only make sense in POST request). Or maybe you meant to have a Method parameter in your function, itself.
But, setting all of that aside, hopefully you now see why you received the compiler error that you did.