I'd like to know if there is any possibility to check if the application is using a network connection now to do something.
The application has a background service which is uploading data and the user may also press a button to download data. I do not want this user to be able to download, until the background process is finished.
Does the framework provide something to check if the connection is used?
I would suggest using BOOL property in your method where the background uploading codes are.
Then in your button's sender method, do something like this:
if (!upLoading)
{
// Your Downloading codes
}
else
{
// Show an alert here
}
Related
I am having problems with understanding how to approach this problem as I am really new to xamarin and android both.
My problem is the following: I need to develop an android app, which takes photos of things and uploads them to a rest server. The confusing part is that the users have really poor connection, so I need to check the internet connection constantly and try to upload the photos when the internet is there. This check needs to be done in the background so the user wont notice any lag.
When the user clicks on "save" the app should save the photo and metadata to a local database or file (json or sqlite) and upload them when the internet is there.
I have tried many different approaches but failed due to lack of understanding how android threading and services work. (Bound service, Foregroundservice, SQLite)
As I dont have much time to research and test all the posibilities, I am asking you guys: How can I do this ?
Thanks for your understanding.
There is one nuget plugin Xam.Plugin.Connectivity for check internet continuously, and you can manage your code in event of this plugin.
For background, you need to create one background thread and you can call it from ConnectivityChanged event.
CrossConnectivity.Current.ConnectivityChanged += (object sender, Plugin.Connectivity.Abstractions.ConnectivityChangedEventArgs e) =>
{
if(e.IsConnected){
//your code here for fetching data when internet connected.
//Create task for background process
Task.Run(() =>
{
//your code for background
}).ConfigureAwait(false);
}
}
I am currently developing an iOS app that takes the streamable url of a music file from dropbox and plays it on the device.
When the user clicks a song, it opens a view controller and there, i want to have the option to download the file. So i have an IBAction:
- (IBAction)availableOfflinePressed:(id)sender {
NSString *trackPath = sharedApp.trackTitle;
NSLog(#"Available offline pressed for %#", trackName);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Started downloading...");
[self.restClient loadFile:trackPath intoPath:trackPath];
});
}
Now, even though it throws the "started downloading..." in the app log, the file is actually never downloaded. I know that the dropbox sdk rest client does not execute functions when in the background, that's why i use the GCD on the main thread.
So, can you help me here? am i missing something?
thanks in advance for any help
turned out it was a pretty silly answer!
the restClient was nil and not correctly set within the specific view controller, so it could not fire the dropbox delegate.
Actually, what was needed is to init the restClient as you might already do in your AppDelegate or anything and then set self.restClient.delegate=self; in the viewDidLoad() function of the specific view controller.
thanks everyone for your responses!
happy coding!
Perhaps I have been reading the wrong stuff, but one thing that all of the literatures that I have been reading seem to agree on is that: iOS does not allow background threads to run for longer than ten minutes. That seems to violate one of the greatest principles of app development: the internet should be invisible to your users. So here is a scenario.
A user is going through a tunnel or flying on an airplane, which causes no or unreliable network. At that instant, the user pulls out my email app, composes an email, and hits the send button.
Question: How do I the developer make sure that the email is sent when network becomes available? Of course I am using email as a general example, but in reality I am dealing with a very much simple http situation where my app needs to send a POST to my server.
Side Note: on android, I use Path’s priority job queue, which allows me to set it and forget it (i.e. as soon as there is network it sends my email).
another Side Note: I have been trying to use NSOperationQueue with AFNetworking, but does not do it.
What you want to achieve can be done using a background NSURLSession. While AFNetworking is based on NSURLSession I’m not quite sure if it can be used with a background session that runs while your app doesn’t. But you don’t really need this, NSURLSession is quite easy to use as is.
As a first step you need to create a session configuration for the background session:
let config = URLSessionConfiguration.background(withIdentifier: "de.5sw.test")
config.isDiscretionary = true
config.waitsForConnectivity = true
The isDiscretionary property allows the system to decide when to perform the data transfer. waitsForConnectivity (available since iOS 11) makes the system wait if there is no internet connection instead of failing immediately.
With that configuration object you can create your URL session. The important part is to specify a delegate as the closure-based callbacks get lost when the app is terminated.
let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
To perform your upload you ask the session to create an upload task and then resume it. For the upload task you first create your URLRequest that specifies the URL and all needed headers. The actual data you want to upload needs to be written to a file. If you provide it as a Data or stream object it cannot be uploaded after your app terminates.
let task = session.uploadTask(with: request, fromFile: fileUrl)
task.resume()
To get notified of success or failure of your upload you need to implement the URLSessionDataDelegate method urlSession(_:task:didCompleteWithError:). If error is nil the transfer was successful.
The final piece that is missing is to handle the events that happened while your app was not running. To do this you implement the method application(_:handleEventsForBackgroundURLSession:completionHandler:) in your app delegate. When the system decides that you need to handles some events for background transfers it launches your app in the background and calls this method.
In there you need first store the completion handler and then recreate your URLSession with the same configuration you used before. This then calls it’s delegate for the events you need to handle as usual. Once it is done with the events it calls the delegate method urlSessionDidFinishEvents(forBackgroundURLSession:). From there you need to call the completion handler that was passed to your app delegate.
The session configuration provides some more options:
timeoutIntervalForResource: How long the system should try to perform your upload. Default is 7 days.
sessionSendsLaunchEvents: If false the app will not be launched to handle events. They will be handled when the user opens the app manually. Defaults is true.
Here is a small sample project that shows how everything fits together: https://github.com/5sw/BackgroundUploadDemo
Your app needs to store the data internally and then you either need something which will cause the app to run in the background (but you shouldn't necessarily add something specially if you don't already have a reason to be doing it) or to wait until the user next brings the app to the foreground - then you can check for a network connection and make the call.
Note that e-mail is very different to a POST, because you can pass an e-mail off to the system mail app to send for you but you can't do exactly the same thing with a POST.
Consider looking also at NSURLSessionUploadTask if you can use it.
In three words: you don't.
And that's actually a good thing. I certainly do not want to have to think and speculate about my last 20 apps, if they are still running in the background, using memory and battery and bandwidth. Furthermore, they would be killed if more memory is needed. How would the user be able to predict if it completed its task successfully? He can't, and need to open the app anyhow to check.
As for the email example, I'd go with showing the email as "pending" (i.e. not sent), until it transferred correctly. Make it obvious to the user that he has to come back later to fulfill the job.
While every developer thinks that his app has an extremely good reason for backgrounding, reality is, for the user in 99% it's just a pain. Can you say "task manager"? ;-)
I wrote a pod that does pretty much this - https://cocoapods.org/pods/OfflineRequestManager. You'd have to do some work listening to delegate callbacks if you want to monitor whether the request is in a pending or completed/failed state, but we've been using it to ensure that requests go out in poor or no connectivity scenarios.
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())
before developping iPhone applications, i thought that any time the iPhone was doing network access, it started the Activity Indicator.
Now that i'm learning to make applications, i understand that it's not the case. The network activity indicator only appears when we decide to make it appear, even if there is no network at all.
Just stop me if i'm wrong.
If i'm not, is there a way to be sure the network is being used by my application or not ?
I'm doing an app based on Evernote SDK and when i launch a Evernote creation, i'm not using any NSURLConnection or things like that and i can't be sure whether it's downloading or uploading stuff. When should i start the Activity Indicator ? and when should i stop it ?
Are there rules ? are there standard methods to know that ?
Thanks
Instead of trying to "make sure if the network is used or not" by your app, you should rather tie the act of showing the indicator to actions. I. e., when you start a networking operation, you show it, and when the completion or error callback of the networking operation is called, you hide it. Of course if you're executing multiple parallel operations, then you need to count the number of active operations. Something like this:
int nNetworkOps = 0;
- (void)startNetworkingOperation
{
nNetworkOps++;
[[UIApplication sharedApplication] setNetworkActivityIndicatorEnabled:YES];
[NSURLConnection sendAsynchronousRequest:rq queue:q completionHandler:^(NSURLResponse *resp, NSData *d, NSError *e) {
[self anOpHasFinished];
}];
}
- (void)anOpHasFinished
{
if (--nNetworkOps == 0) {
// hide the activity indicator
// You have to do this on the main thread
// (left to you as an exercise)
}
}
There are not strict rules about usage of Activity Indicator. You should use indicator to tell user that actually something happens in background.
For example if you are creating app that need to search using some web service, user enters keyword and presses button, there you contact the server, server returns the result and new view with search result is presented. Pay attention at moment when you tap the search button, if you dont show activity indicator, user may think that search is not performed, and he will try to press several more times until he become nervous and closes our app. If we show activity indicator user will know that search is performing in background and he will be patient and he will wait for the results.
There are some scenarios where you have network communication, but you dont show activity indicator. For example application that sends gps location to server, on every location update. Here you dont want user to know when network communication occurs because it is unnecessary and may become frustrating during the time.
My app load some data from server and show it on the display. When app closed I want to check storage on the device and if not all data hadn't been loaded yet by user, then load data from server to device. Let me clarify I want do it when application not worked.
I read about background processes, but don't understand how it works and how to implement my feature via them. Can you describe how it should work in balckberry? All help would be appreciated
If you want the app to run in the background then you can override the onClose method in your main screen.
public boolean onClose() {
UiApplication.getUiApplication().requestBackground();
return true;
}