では、iOS 7 がより広範なバックグラウンド モードをサポートすることで、最終的に iOS で Android サービスと同等のものを使用できるようになるのでしょうか?
私が求めているのは、基本的にアプリ A をバックグラウンドで実行し、1 つ以上のアプリ B と C をそのアプリと通信させることです (アプリ A の GUI を表示せずに)。
接続とプッシュ通知を使用することはオプションではありませんが、これは推奨される方法であることに注意してください。何か案は?
では、iOS 7 がより広範なバックグラウンド モードをサポートすることで、最終的に iOS で Android サービスと同等のものを使用できるようになるのでしょうか?
私が求めているのは、基本的にアプリ A をバックグラウンドで実行し、1 つ以上のアプリ B と C をそのアプリと通信させることです (アプリ A の GUI を表示せずに)。
接続とプッシュ通知を使用することはオプションではありませんが、これは推奨される方法であることに注意してください。何か案は?
編集:期待どおりに動作しません。最適な解決策については、この回答を参照してください:プッシュ通知
編集:次の解決策は、ユーザーがアプリを使用している間のみ、同期を維持するために役立ちます。
バックグラウンドでタスクを永続的に実行する方法はありませんが、有限長のタスクを使用してそれを行うことができます。有限長を作成すると、アプリがアクティブな間は常に実行されますが、ホームボタンをクリックすると、 ios では、タスクを実行して無効にするのに 10 分しか与えられませんが、確実に終了する前に最後のアクションを実行できる「無効化ハンドラー ブロック」を作成する機会が与えられます。
そのため、そのハンドラー ブロックを使用して別の時間に有限長のタスクを呼び出す場合、タスクを 10 分間実行し、そのタスクが終了したら、他の 10 分間同じタスクを呼び出すことでサービスをシミュレートできます。
インターフェイス「サービス」を作成するプロジェクトでそれを使用します。ここにコードを示します。
//
// 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
このクラスを使用してサービスを実行しますが、非常に長い間テストしません。私が行った最高のテストは、シミュレーターで 16 時間続き、すべて正常に動作しました!
EDIT:シミュレーターでテストされましたが、アプリケーションが終了した後、電話では機能しません。
例を挙げましょう:
// 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
アプリのデリゲートまたはサービスを発生させる必要がある場所で、次の行を記述します。
Service myService = [[SomeService alloc] initWithFrequency: 60]; //execute doInBackground each 60 seconds
[myService startService];
停止する必要がある場合は、次のようにします。
[myService stopService];
必要以上に説明してしまったかもしれませんが、どなたにもわかりやすくお伝えしたいと思います!その助けを願っています。私の英語で申し訳ありません。
いいえ、Android サービスに相当するものはありません。MansApps コードは、少なくとも iOS7 では機能しません。[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
有効期限ハンドラ内のの呼び出しは、アプリがフォアグラウンドに戻ったときにのみ返されます。つまり、[self startBackgroundTask];
アプリがバックグラウンドにある場合、 の呼び出しは実行されません。
アプリが以下にリストされている機能のいずれも実装していない場合、基本的には不可能です。また、アプリをストアにアップロードする前に調査することはほとんどありません。その権限の使用を正当化する必要があります。
これについて、Apple は次のように述べています。
長時間実行タスクの実装
実装するのにより多くの実行時間を必要とするタスクについては、特定のアクセス許可を要求して、一時停止せずにバックグラウンドで実行する必要があります。iOS では、特定の種類のアプリのみがバックグラウンドで実行できます。
これらのサービスを実装するアプリは、サポートするサービスを宣言し、システム フレームワークを使用してそれらのサービスの関連する側面を実装する必要があります。サービスを宣言すると、使用するサービスをシステムに認識させることができますが、アプリケーションの中断を実際に防止するのはシステム フレームワークである場合もあります。
私は最善の標準的な解決策を見つけました:
(Matthijs Hollemans による元の投稿、Ali Hafizji による更新)。
iOS では、アプリはバックグラウンドで多くのことを行うことができません。アプリは限られた一連のアクティビティのみを実行できるため、バッテリー寿命が節約されます。しかし、興味深いことが起こったときに、ユーザーが現在アプリを使用していなくても、そのことをユーザーに知らせたい場合はどうすればよいでしょうか? たとえば、ユーザーが新しいツイートを受け取った、お気に入りのチームが試合に勝った、夕食の準備ができたなどです。アプリは現在実行されていないため、これらのイベントを確認できません。幸いなことに、Apple はこれに対する解決策を提供しています。アプリが継続的にイベントをチェックしたり、バックグラウンドで作業を行ったりする代わりに、代わりにサーバー側コンポーネントを作成してこれを行うことができます。そして、関心のあるイベントが発生すると、サーバー側コンポーネントはアプリにプッシュ通知を送信できます! プッシュ通知でできることは 3 つあります。
チュートリアル リンク: http://maniacdev.com/2011/05/tutorial-ios-push-notification-services-for-beginners