Dev Environment :
Xcode 8, XCode 9
AFNetworking for network request
My app need to upload some media to server, when its done i need to call the api to POST some JSON Data to server in both case Application in Foreground and Background
My problem is:
When application is active, i making request upload media to server (request 1) and press Home button (application enter background). All the media was uploading success in the background, in success block of upload media request (request 1) i making another request to POST some JSON data to server (request 2) but this request (request 2) can't excute in the background. When i enter the application (application enter foreground). (request 2) trigger automatically.
I need to make (request 2) execute in the background. Is it possible to do this?
Please help ! Many thanks !
At background upload file that you need apply more time.
The iOS has 3mius give you using.
You can review "beginBackgroundTaskWithExpirationHandler".
Related
I have develop a HTTP module for making upload download request using URLSession Background sessions.
The HTTP module work in Serialize mode as specified in URLSession doc by passing nil to queue.
On download complete urlSession(_:downloadTask:didFinishDownloadingTo:) i do parsing.Based on parsing make request for other file from the same module.
Everything works OK in foreground.
But as i move the application to background by pressing home button downloading and parsing stops.
Because of which i can't able to make another file request in background.
And if application move to foreground downloading will resume.
Can any one help me out for this ?
I have an iOS app that authenticates to a remote API. The server gives back a token that is used for all the next requests. The authentication call is a simple POST to /api/auth.
My question is: where should I make this call in the app ?
I don't know if I should use it in the AppDelegete (willEnterForeground or didBecomeActive), because it may slow down the app launch. Moreover, this is asynchronous and if I try to make other requests in some controllers while the token hasn't returned, there will be errors.
So I thought about doing it in the root controller, but in the case the app was in the background for a long time and comes to foreground in another controller it doesn't work...
The last option would be to watch errors on every call, and re-authenticate when the server responds with a 'token expired' error. In that case I should probably have a special class for HTTP requests and error handling ?
I don't know what option is the best...
I'm working on an iOS app which makes use of the location background mode to track user visits and then sends some data over to my server. However, I have been experiencing some weird network communication problems. The only symptom is that not all gathered data gets sent to the server.
Here is more information on the problem:
My server makes logs of everything received. There were no server-side errors and every client request was successfully logged.
The client app creates a local notification when the locationManager:didVisit: method is called. This notification appears as expected when you arrive and depart at some location. Then, it calls the server over HTTPS and posts another notification, which doesn't appear every time. The whole setup looks like this:
// This code is executed from locationManager:didVisit: when the app is in background.
let myVisit: CLVisit! = ... // the received visit
self.postLocalNotification("Visit received!", visit: myVisit)
let task = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler(nil)
Alamofire.request(.POST, apiMethod("visit"), parameters: params, encoding: .JSON)
.responseJSON { (request, response, JSON, error) in
// This gets executed only some time, wtf?
self.postLocalNotification("Visit reported!", visit: myVisit)
UIApplication.sharedApplication().endBackgroundTask(task)
}
Therefore, I conclude I'm doing something wrong, yet I don't see what. I have checked the article on background app execution and my app seems to comply with it. What else could I be missing?
Is your app in registered to support background mode?
Since you receive location updates, your app should qualify to be set to run in background mode. Set the "Required background mode" in your plist file.
That will let it fully run in the background and you can get rid of the beginBackgroundTask lines.
The beginBackgroundTaskWithExpirationHandler methods are typically used to request a little extra time for a current task to be completed provided that your app is in the foreground and it moves to the background in the middle of a task. To me it sounds like you want to run in full background mode.
With that said, you should still detected that your program is backgrounded and avoid running unneeded cpu intensive tasks to save battery life.
I need something similar to Facebook's offline post capabilities. Basically I want users to create content locally on the device regardless of connection state, and whenever internet becomes available it should POST/PUT to the server.
I've searched the internet for a solution and I found that NSURLSessionUploadTask can be used for POST-ing in the background. But I couldn't figure out if the following scenarios are supported:
Will my task remain in the background queue when the user is offline and will the operating system try to execute items in the queue upon reconnecting with a network?
What happens if the application is force-closed by the user or crashes?
What happens if the operation fails?
First of all, background NSURLSession allows file upload only. If that is ok for you:
The task will be in the queue until it receives a server answer.
If your app is force-closed, the task will still be executing. When the request is done, your app will be launched in non-interactive background state and receive application:handleEventsForBackgroundURLSession:completionHandler:. After you process the signal and call the completion handler or 30 second timeout, the app will be closed.
I the operation fails, you will receive URLSession:task:didCompleteWithError:
There is a good tutorial on background NSURLSessions. I suggest you to read all 4 parts of this great article.
If file upload is not an option for you, i suggest you to save information into local database and then wait for internet is reachable. (a good approach here is use of Reachability library, Alamofire allows to do that too). When internet becomes available, simply call your http requests with saved data.
We were running into connectivity issues with our internal apps, so we wrote a Swift framework that allows any network operations to be enqueued and sent whenever the device has access to the internet -
https://cocoapods.org/pods/OfflineRequestManager. You'll still have to handle the network request itself within the object conforming to OfflineRequest, but it sounds like a good fit for your use case.
The simplest use case would look something like the following, though most actual cases (saving to disk, specific request data, etc.) will have a few more hoops to jump through:
import OfflineRequestManager
class SimpleRequest: OfflineRequest {
func perform(completion: #escaping (Error?) -> Void) {
doMyNetworkRequest(withCompletion: { response, error in
handleResponse(response)
completion(error)
})
}
}
///////
OfflineRequestManager.defaultManager(queueRequest: SimpleRequest())
I am developing an iPhone app which is using CocoaHTTPServer for making remote server communication.
The app will send the request details to the CocoaHTTPServer which will store the request locally. Once the internet connectivity is available, CocoaHTTPServer will send the request to remote server & will get the server response now CocoaHTTPServer has to send this response back to the app,
But I am confused how to implement it. Is there any inter app communication api for the same?
Any suggestions are greatly appreciated.
Well , I haven't workaround CocoaHTTP server classes so can't explain you verywell but I found there are couple of tutorials will surly guide you.
Thanks to Matt Gallagher for such a detailed article.
You can listen for a connection using NSFileHandle class
listeningHandle = [[NSFileHandle alloc]
initWithFileDescriptor:fileDescriptor
closeOnDealloc:YES];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(receiveIncomingConnectionNotification:)
name:NSFileHandleConnectionAcceptedNotification
object:nil];
[listeningHandle acceptConnectionInBackgroundAndNotify];
When receiveIncomingConnectionNotification: is invoked, each new incoming connection will get its own NSFileHandle. If you're keeping track, you can handle received message
if(CFHTTPMessageIsHeaderComplete(incomingRequest))
{
HTTPResponseHandler *handler =
[HTTPResponseHandler
handlerForRequest:incomingRequest
fileHandle:incomingFileHandle
server:self];
[responseHandlers addObject:handler];
[self stopReceivingForFileHandle:incomingFileHandle close:NO];
[handler startResponse];
return;
}
Note : please go through the full article, it has nice explanation.
Apart from this you may have look on this as well.
Hope this will give you some idea.
You question is focussing on background proces.
When an App goes into background, it get very limited time to finish things up. After that the App freezes in background. That is not a good situation to start communication.
Apple states clearly that the priority is always on the running foreground tasks.
The Notification mechanism (as listed by RDC above) is created to handle external events. During such a wake up you can send/receive a little bit of data, however you'll get minimal priority. Since timing is important in communication, I would not go for that either.
I suggest checking communication during the wakeup call and start activities then. And use the Notification mechanism to wakeup the user, that network is up again.
URL scheme can be used to send the response back to the app. The response from the remote server can be set as a parameter in the URL. The CocoaHTTPServer can invoke the other app which will be the handler of this unique URL. The below link provides more information on the same.
Inter-AppCommunication using URL scheme