AFNetworking 3.0 を使用して、アプリケーションで大きなビデオ ファイルをダウンロードしようとしています。AFNetworking を使用してバックグラウンドでファイルをダウンロードする方法に関する特定のドキュメントは見つかりませんでした。
AFNetworking はAFURLSessionManagerとAFHTTPSessionManagerを使用し、それ自体がNSURLSessionのすべてのデリゲートを実装していることを知っています。
これまでに行ったことは、 backgroundSessionConfugarationを作成し、これを使用してダウンロードするファイルを開始することです。
self.manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:bgDownloadSessionIdentifier]];
[self.manager downloadTaskWithRequest:request progress:nil destination:nil completionHandler:nil];
ダウンロードが開始したら、アプリケーションをバックグラウンドに置きます。私がこれまでに見つけたのは、アプリが 20 分までバックグラウンドで実行され、ダウンロードが成功したことです。しかし、appDelegate のapplication:handleEventsForBackgroundURLSessionは呼び出されないため、setDidFinishEventsForBackgroundURLSessionBlockも呼び出されません。
setDidFinishEventsForBackgroundURLSessionBlockが呼び出されたときにのみ通知を表示したい。
これを使用してマネージャーを初期化すると。( backgroundSessionConfigurationの代わりに)
self.manager = [AFHTTPSessionManager manager];
Still アプリは、バックグラウンドで 20 分後にファイル全体をダウンロードできます。
私の問題は、アプリケーションが 20 分まで実行され、ダウンロードが完了した理由です。理想的には、iOS は 10 分後にアプリを強制終了する必要があります。また、セッションの完了後にapplication:handleEventsForBackgroundURLSessionが呼び出されない理由。
このAFNetworking 2.0 とバックグラウンド転送については既に言及しましたが、うまくいかないようです。
機能からのバックグラウンド モードは、ON または OFF のいずれかであり、アプリケーションには何の影響もありません。
私を助けてください、または私がここで間違っていることを教えてください。
サンプルコードをここにアップロードしました。 https://www.dropbox.com/s/umwicuta2qzd3k1/RSNetworkKitExample.zip?dl=0
AppDelegate.m
-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
NSLog(@"===== background session completed in AppDelegate ===== ");
if([identifier isEqualToString:bgDownloadSessionIdentifier]){
[RSDownloadManager sharedManager].backgroundSessionCompletionHandler = completionHandler;
}
}
================================================== ==
ViewController.m
- (IBAction)downloadVideoInBackground:(id)sender {
NSString *videoURL = @"http://videos1.djmazadownload.com/mobile/mobile_videos/Tum%20Saath%20Ho%20(Tamasha)%20(DJMaza.Info).mp4";
[RSDownloadManager sharedManager].backgroundSessionCompletionHandler = ^{
NSLog(@"===== background session completed in ViewController ===== ");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = @"Download Complete!";
localNotification.alertAction = @"Background Transfer Download!";
//On sound
localNotification.soundName = UILocalNotificationDefaultSoundName;
//increase the badge number of application plus 1
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
};
[[RSDownloadManager sharedManager] downloadInBackgroundWithURL:videoURL downloadProgress:^(NSNumber *progress) {
NSLog(@"Video download progress %.2f", [progress floatValue]);
} success:^(NSURLResponse *response, NSURL *filePath) {
NSLog(@"Video download completed at Path %@", filePath);
} andFailure:^(NSError *error) {
NSLog(@"Error in video download %@", error.description);
}];
}
================================================== ==
RSDownloadManager.h
#import <Foundation/Foundation.h>
#import "AFHTTPSessionManager.h"
static NSString *bgDownloadSessionIdentifier = @"com.RSNetworkKit.bgDownloadSessionIdentifier";
@interface RSDownloadManager : NSObject
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@property (nonatomic, copy) void (^backgroundSessionCompletionHandler)(void);
+(instancetype)sharedManager;
-(NSURLSessionDownloadTask *)downloadInBackgroundWithURL:(NSString *)urlString downloadProgress:(void (^)(NSNumber *progress))progressBlock success:(void (^)(NSURLResponse *response, NSURL *filePath))completionBlock andFailure:(void (^)(NSError *error))failureBlock;
@end
================================================== ==
RSDownloadManager.m
@implementation RSDownloadManager
#pragma mark - Singleton instance
+(instancetype)sharedManager
{
static RSDownloadManager *_downloadManager = nil;
static dispatch_once_t token;
dispatch_once(&token, ^{
if (!_downloadManager) {
_downloadManager = [[self alloc] init];
}
});
return _downloadManager;
}
#pragma mark - Init with Session Configuration
-(void)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
self.manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
//self.manager = [AFHTTPSessionManager manager];
}
#pragma mark- Handle background session completion
- (void)configureBackgroundSessionCompletion {
typeof(self) __weak weakSelf = self;
[self.manager setDidFinishEventsForBackgroundURLSessionBlock:^(NSURLSession *session) {
if (weakSelf.backgroundSessionCompletionHandler) {
weakSelf.backgroundSessionCompletionHandler();
weakSelf.backgroundSessionCompletionHandler = nil;
}
}];
}
#pragma mark- download in background request Method
-(NSURLSessionDownloadTask *)downloadInBackgroundWithURL:(NSString *)urlString downloadProgress:(void (^)(NSNumber *))progressBlock success:(void (^)(NSURLResponse *, NSURL *))completionBlock andFailure:(void (^)(NSError *))failureBlock {
/* initialise session manager with background configuration */
if(!self.manager){
[self initWithSessionConfiguration:[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:bgDownloadSessionIdentifier]];
}
[self configureBackgroundSessionCompletion];
/* Create a request from the url */
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSURLSessionDownloadTask *downloadTask = [self.manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
if(progressBlock) {
progressBlock ([NSNumber numberWithDouble:downloadProgress.fractionCompleted]);
}
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
if(error) {
if(failureBlock) {
failureBlock (error);
}
}
else {
if(completionBlock) {
completionBlock (response, filePath);
}
}
}];
[downloadTask resume];
return downloadTask;
}