Alamofire not working while called from background fetch - ios

I'm using background fetch in an iOS app to schedule some notifications and I need to fetch some data from server But when i create an Alamofire request the surver returns the data but alamofire does not calles my compilation handler (responseString)
the exact same code works perfectly while my app is on forground.
Alamofire.request(url, method: method ?? HTTPMethod.get, parameters: parameters,
encoding: encoding ?? URLEncoding.default, headers: headers)
.responseString{
(afResponse : DataResponse<String>) -> Void in
....
}
I used AlamofireNetworkActivityLogger to check weather the response is created and fetched and the result was true. but my compilation handler not getting called!
any thing else should I consider while using Alamofire in background?

Have you tested if it is working as suggested in Alamofire network calls not being run in background thread
We may have to start the call from background thread instead of the main thread (as it is the default behaviour).

Related

iOS Alamofire - Streaming JSON lines first response issue

Using Alamofire 4.9.0.
I am trying to implement handling streaming APIs in JSON lines format. Here's how:
stream = Alamofire.request(url, method: HTTPMethod.get,
headers: TTSessionManager.headers)
.validate()
.stream(closure: { (data) in
// parsing JSON lines ...
})
.response(completionHandler: { (response) in
// error handling ...
})
Now the issue is that the first response takes some time to return. And when it does I get a couple of JSON lines in one big batch. After that stream continues to normally respond with a new JSON line per response coming through the stream.
Has anyone encountered this behaviour? I'm wondering wether there is some additional session or request setup needed in order for this to work normal (line per response) from the start. When inspecting the response.metrics after canceling the request a lot of the fields are null so I can't for sure say wether some of the initial connection steps are the issue:
(Domain Lookup Start) (null)
(Domain Lookup End) (null)
(Connect Start) (null)
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) (null)
So the problem here was that the response header didn't have Content-Type set to application/json. When this header is not set properly, URLSession data task will buffer first 512 bytes of response.
More info can be found here: https://developer.apple.com/forums/thread/64875

How to abort iOS Alamofire Multipart Upload on failure in encoding

I have implemented a working multipart upload on iOS using Alamofire. However from time to time an error occurs during the creation of the multipart upload. I would like to handle that error gracefully (currently it calls fatalError and crashes the whole app. I would rather like to do something like throwing and aborting the upload.
Some pseudo code as explanation.
Alamofire.upload(multipartFormData: {data in
if self.create() == .failure {
throw error
},
usingThreshold: UInt64.init(),
to: url,
method: .post,
headers: headers,
encodingCompletion: {error in
self.onEncodingComplete()}
)
Of course this throw does not work, since the closure is not throwing. Does anyone have a working solution for this?

Mocking Alamofire interface to handle response cases in tests

How can Alamofire calls such as request, download, upload be mocked so that one has control over the response and the flow in the callback?
I would like to test the response closures that Alamofire calls, without hitting the network. I would also like this to be self contained, without doing response rewrites with Charles.
It doesnt seem to be possible to mock certain Alamofire objects directly due to the internals and private methods etc.
Has anyone successfully managed to test these Alamofire response handlers?
E.g.
Alamofire.request("https://httpbin.org/get").responseJSON { response in
// using the mocked response here to control
// and assert execution flow inside this callback
}
Or
public func should(_ manager: SessionManager,
retry request: Request,
with error: Error,
completion: #escaping RequestRetryCompletion) {
// using the mocked request.task?.response here to control
// and assert execution flow inside this callback
}
I also cant seem to initialize any type of Alamofire Request (e.g. DataRequest) as compiler complains with DataRequest() and there are no initializers in the class.

Alamofire 4 finish request in the background

I'm using alamorefire to make calls to an API, but I figured that if I put the app in the background, the call will pause and I don't want that. I want it to load and then, when I bring the app to the foreground, I can use the requested data on the UI. How can this be done? At the moment I just do plain requests like this:
Alamofire.request(url, method: .get, parameters: params, headers: header())
.responseJSON{response in switch response.result {
I've tried using the following alamofire configuration:
let configuration = URLSessionConfiguration.background(withIdentifier: "com.cmpny.myapp.background")
let manager = Alamofire.SessionManager(configuration: configuration)
manager.request(url, method: .get, parameters: params, headers: headers())
This gives me the following error:
Request failed with error: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=http://url, NSLocalizedDescription=cancelled, NSErrorFailingURLKey=http://url}
You should use UIBackgroundTaskIdentifier for this purpose.
Apple doc:
https://developer.apple.com/reference/uikit/uiapplication/1623031-beginbackgroundtaskwithexpiratio
Similar question:
https://stackoverflow.com/a/31751337/1689376
Hope this helps ;)

What is the difference between the two request methods of alamofire?

I was just playing with Alamofire framework and making few api calls. However I observed there are two request methods in alamofire :
public func request(method: Method, URLString: URLStringConvertible, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL, headers: [String: String]? = nil) -> Request{...}
and
public func request(URLRequest: URLRequestConvertible) -> Request {...}
I found this really interesting, because the first method prototype is detailed and is easily understood. But the second one is quite confusing, I know that it takes a parameter which conforms to URLRequestConvertible protocol that is defined by Alamofire.
In the second request prototype the HTTP Method (GET or POST) that needs to be used is never specified, so how does the alamofire knows which HTTP method to be used. Is there a way to let alamofire know which http method to use while making request.
Also what are the other significant differences between these two methods (if any) and which one is preffered and why?
Thank you.
The rendition of request without a method or parameters is presuming that you manually prepared the NSMutableURLRequest that includes the appropriate HTTPMethod, the HTTP headers (e.g. Content-Type, etc.), and HTTPBody.
You wouldn't generally use this rendition of the request method (we use Alamofire precisely to get us out of the weeds of manually constructing requests), but is useful when you have to construct a request that Alamofire cannot otherwise prepare (e.g. Sending json array via Alamofire).

Resources