So with iOS 7 supporting a broader background mode, is it possible to finally have an equivalent to Android Service on iOS?
What I am after is essentially running app A in the background and have one or more apps B and C talk to that app (without showing the GUI of app A).
Please note that using connectivity and push notifications may not be an option although this is the recommended way of doing so. Any ideas?
Google's Android and Apple's iOS are operating systems used primarily in mobile technology, such as smartphones and tablets. Android, which is Linux-based and partly open source, is more PC-like than iOS, in that its interface and basic features are generally more customizable from top to bottom.
Fast processors for better performance The iPhones have a series of processors that reportedly deliver better performance than most Android phones. In addition, Apple blends hardware and software well, making the iPhone more efficient and effective.
Both mobile operating systems have decent records and safeguards when it comes to security, but Android, being more open, has more vectors for malware to enter your phone. In particular, apps are more prone to bring trouble in Android, especially if you install from an alternative app store.
EDIT: Not working as expected. See this answer for best solution: Push Notifications
EDIT: The next solution is only useful while the user is in the app to maintain it synced.
There is no way to perform tasks in the background permanently, but you can use the finite-length tasks to do that, when you make a finite-length, this gonna run always while the app is active, but when you click home button, ios gives you only 10 min to perform your task and invalidate it, but it gives you a chance to make a 'invalidate handler block' where you can do last actions before finish definitely.
So, if you use that handler block to call a finite-length task other time, you can simulate a service by run a task for 10 min and when its end, call its same for other 10 min and consequently.
I use that in a project creating a interface 'Service'. I let you here the code:
//
// Service.h
// Staff5Personal
//
// Created by Mansour Boutarbouch Mhaimeur on 30/09/13.
// Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Service : NSObject
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask;
@property (nonatomic) NSInteger frequency;
@property (nonatomic, strong) NSTimer *updateTimer;
- (id) initWithFrequency: (NSInteger) seconds;
- (void) startService;
- (void) doInBackground;
- (void) stopService;
@end
//
// Service.m
// Staff5Personal
//
// Created by Mansour Boutarbouch Mhaimeur on 30/09/13.
// Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//
#import "Service.h"
@implementation Service
@synthesize frequency;
-(id)initWithFrequency: (NSInteger) seconds{
if(self = [super init]){
self.frequency = seconds;
return self;
}
return nil;
}
- (void)startService{
[self startBackgroundTask];
}
- (void)doInBackground{
//Español //Sobreescribir este metodo para hacer lo que quieras
//English //Override this method to do whatever you want
}
- (void)stopService{
[self.updateTimer invalidate];
self.updateTimer = nil;
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
- (void) startBackgroundTask{
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:frequency
target:self
selector:@selector(doInBackground)
userInfo:nil
repeats:YES];
self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundTask];
}];
}
- (void) endBackgroundTask{
[self.updateTimer invalidate];
self.updateTimer = nil;
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
[self startBackgroundTask];
}
@end
With this class i perform my services, but i don't test it for a really long time. The best test i does lasted 16 hours in simulator and everything works fine!
EDIT: That was tested on the simulator, but in phone doesnt work after the application has been terminated.
I let you a example:
// SomeService.h
@interface SomeService : Service
@end
// SomeService.m
#import "SomeService.h"
@implementation SomeService
// The method to override
- (void)doInBackground{
NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining);
NSLog(@"Service running at %.1f seconds", [self getCurrentNetworkTime]);
}
// Your methods
- (long) getCurrentNetworkTime{
return ([[NSDate date] timeIntervalSince1970]);
}
@end
And in your app delegate or where you need to raise the service, you write the next line:
Service myService = [[SomeService alloc] initWithFrequency: 60]; //execute doInBackground each 60 seconds
[myService startService];
And if you need to stop it:
[myService stopService];
May have explained more than necessary, but i want to keep it clear for anyone! I hope its help and sorry for my english.
No, there is no equivalent to an Android Service. MansApps code does not work, at least not on iOS7. A call of [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
in the expiration handler will only return when the app comes back to the foreground, i.e., the call of [self startBackgroundTask];
will not be executed when the app stays in the background.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With