第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

AF網(wǎng)絡(luò)和后臺(tái)傳輸

AF網(wǎng)絡(luò)和后臺(tái)傳輸

jeck貓 2019-11-26 10:26:56
對(duì)于如何利用新的iOS 7 NSURLSession后臺(tái)傳輸功能和AFNetworking(版本2和3),我有些困惑。我看到了WWDC 705 - What’s New in Foundation Networking會(huì)話,他們演示了后臺(tái)下載,該下載在應(yīng)用終止甚至崩潰后仍然繼續(xù)。這是使用新的API application:handleEventsForBackgroundURLSession:completionHandler:以及會(huì)話的委托人最終將獲得回調(diào)并可以完成其任務(wù)的事實(shí)來(lái)完成的。因此,我想知道如何將其與AFNetworking一起使用(如果可能)以繼續(xù)在后臺(tái)下載。問題是,AFNetworking方便地使用基于塊的API來(lái)執(zhí)行所有請(qǐng)求,但是如果應(yīng)用終止或崩潰,這些塊也將消失。那么我該如何完成任務(wù)呢?也許我在這里想念什么...讓我解釋一下我的意思:例如,我的應(yīng)用程序是一個(gè)照片消息傳遞應(yīng)用程序,可以說我有一個(gè)PhotoMessage代表一條消息的對(duì)象,并且該對(duì)象具有諸如state -描述照片下載的狀態(tài)。resourcePath -最終下載的照片文件的路徑。因此,當(dāng)我從服務(wù)器收到新消息時(shí),我創(chuàng)建了一個(gè)新PhotoMessage對(duì)象,并開始下載其照片資源。PhotoMessage *newPhotoMsg = [[PhotoMessage alloc] initWithInfoFromServer:info];newPhotoMsg.state = kStateDownloading;self.photoDownloadTask = [[BGSessionManager sharedManager] downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {    NSURL *filePath = // some file url    return filePath;} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {    if (!error) {        // update the PhotoMessage Object        newPhotoMsg.state = kStateDownloadFinished;        newPhotoMsg.resourcePath = filePath;    }}];[self.photoDownloadTask resume];   如您所見,我根據(jù)完成PhotoMessage的響應(yīng)使用完成塊來(lái)更新該對(duì)象。我該如何通過后臺(tái)傳輸來(lái)實(shí)現(xiàn)?此完成程序塊將不會(huì)被調(diào)用,因此,我無(wú)法更新newPhotoMsg。
查看完整描述

3 回答

?
慕碼人8056858

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊

一些想法:


您必須確保執(zhí)行“ URL加載系統(tǒng)編程指南”的“ 處理iOS后臺(tái)活動(dòng)”部分中概述的必要編碼:


如果您NSURLSession在iOS 中使用,則下載完成后會(huì)自動(dòng)重新啟動(dòng)您的應(yīng)用。應(yīng)用程序的application:handleEventsForBackgroundURLSession:completionHandler:應(yīng)用程序委托方法負(fù)責(zé)重新創(chuàng)建適當(dāng)?shù)臅?huì)話,存儲(chǔ)完成處理程序,并在會(huì)話調(diào)用您的會(huì)話委托人的URLSessionDidFinishEventsForBackgroundURLSession:方法時(shí)調(diào)用該處理程序。


該指南顯示了您可以執(zhí)行的一些示例。坦率地說,我覺得在WWDC 2013視頻的后半部分討論的代碼樣本中的新增基礎(chǔ)網(wǎng)絡(luò)都顯得更加清晰。


AFURLSessionManager如果僅暫停了應(yīng)用程序,則的基本實(shí)現(xiàn)將與后臺(tái)會(huì)話配合使用(假設(shè)您已完成上述操作,則在完成網(wǎng)絡(luò)任務(wù)時(shí),您會(huì)看到調(diào)用的塊)。但是,正如您猜到的那樣,“如果應(yīng)用終止或崩潰” ,傳遞給AFURLSessionManager您創(chuàng)建NSURLSessionTask用于上載和下載的方法的特定于任務(wù)的塊參數(shù)都將丟失。


對(duì)于后臺(tái)上傳,這很煩人(因?yàn)樵趧?chuàng)建任務(wù)時(shí)指定的任務(wù)級(jí)信息進(jìn)度和完成塊將不會(huì)被調(diào)用)。但是,如果您使用會(huì)話級(jí)再現(xiàn)(例如setTaskDidCompleteBlock和setTaskDidSendBodyDataBlock),則會(huì)被正確調(diào)用(假設(shè)在重新實(shí)例化會(huì)話管理器時(shí)始終設(shè)置這些塊)。


事實(shí)證明,丟失塊的問題實(shí)際上對(duì)于后臺(tái)下載而言更成問題,但是那里的解決方案非常相似(不要使用基于任務(wù)的塊參數(shù),而要使用基于會(huì)話的塊,例如setDownloadTaskDidFinishDownloadingBlock)。


另一種選擇是,您可以使用默認(rèn)設(shè)置(非后臺(tái))NSURLSession,但是如果用戶在執(zhí)行任務(wù)時(shí)離開應(yīng)用程序,請(qǐng)確保您的應(yīng)用程序請(qǐng)求一點(diǎn)時(shí)間來(lái)完成上傳。例如,在創(chuàng)建之前NSURLSessionTask,您可以創(chuàng)建一個(gè)UIBackgroundTaskIdentifier:


UIBackgroundTaskIdentifier __block taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {

    // handle timeout gracefully if you can


    [[UIApplication sharedApplication] endBackgroundTask:taskId];

    taskId = UIBackgroundTaskInvalid;

}];

但是,請(qǐng)確保網(wǎng)絡(luò)任務(wù)的完成塊正確通知iOS它已完成:


if (taskId != UIBackgroundTaskInvalid) {

    [[UIApplication sharedApplication] endBackgroundTask:taskId];

    taskId = UIBackgroundTaskInvalid;

}

這沒有背景那么強(qiáng)大NSURLSession(例如,您有有限的可用時(shí)間),但是在某些情況下這可能很有用。


更新:


我以為我會(huì)添加一個(gè)實(shí)際的示例,說明如何使用AFNetworking進(jìn)行后臺(tái)下載。


首先定義您的后臺(tái)經(jīng)理。


//

//  BackgroundSessionManager.h

//

//  Created by Robert Ryan on 10/11/14.

//  Copyright (c) 2014 Robert Ryan. All rights reserved.

//


#import "AFHTTPSessionManager.h"


@interface BackgroundSessionManager : AFHTTPSessionManager


+ (instancetype)sharedManager;


@property (nonatomic, copy) void (^savedCompletionHandler)(void);


@end


//

//  BackgroundSessionManager.m

//

//  Created by Robert Ryan on 10/11/14.

//  Copyright (c) 2014 Robert Ryan. All rights reserved.

//


#import "BackgroundSessionManager.h"


static NSString * const kBackgroundSessionIdentifier = @"com.domain.backgroundsession";


@implementation BackgroundSessionManager


+ (instancetype)sharedManager {

    static id sharedMyManager = nil;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        sharedMyManager = [[self alloc] init];

    });

    return sharedMyManager;

}


- (instancetype)init {

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:kBackgroundSessionIdentifier];

    self = [super initWithSessionConfiguration:configuration];

    if (self) {

        [self configureDownloadFinished];            // when download done, save file

        [self configureBackgroundSessionFinished];   // when entire background session done, call completion handler

        [self configureAuthentication];              // my server uses authentication, so let's handle that; if you don't use authentication challenges, you can remove this

    }

    return self;

}


- (void)configureDownloadFinished {

    // just save the downloaded file to documents folder using filename from URL


    [self setDownloadTaskDidFinishDownloadingBlock:^NSURL *(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location) {

        if ([downloadTask.response isKindOfClass:[NSHTTPURLResponse class]]) {

            NSInteger statusCode = [(NSHTTPURLResponse *)downloadTask.response statusCode];

            if (statusCode != 200) {

                // handle error here, e.g.


                NSLog(@"%@ failed (statusCode = %ld)", [downloadTask.originalRequest.URL lastPathComponent], statusCode);

                return nil;

            }

        }


        NSString *filename      = [downloadTask.originalRequest.URL lastPathComponent];

        NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

        NSString *path          = [documentsPath stringByAppendingPathComponent:filename];

        return [NSURL fileURLWithPath:path];

    }];


    [self setTaskDidCompleteBlock:^(NSURLSession *session, NSURLSessionTask *task, NSError *error) {

        if (error) {

            // handle error here, e.g.,


            NSLog(@"%@: %@", [task.originalRequest.URL lastPathComponent], error);

        }

    }];

}


- (void)configureBackgroundSessionFinished {

    typeof(self) __weak weakSelf = self;


    [self setDidFinishEventsForBackgroundURLSessionBlock:^(NSURLSession *session) {

        if (weakSelf.savedCompletionHandler) {

            weakSelf.savedCompletionHandler();

            weakSelf.savedCompletionHandler = nil;

        }

    }];

}


- (void)configureAuthentication {

    NSURLCredential *myCredential = [NSURLCredential credentialWithUser:@"userid" password:@"password" persistence:NSURLCredentialPersistenceForSession];


    [self setTaskDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *credential) {

        if (challenge.previousFailureCount == 0) {

            *credential = myCredential;

            return NSURLSessionAuthChallengeUseCredential;

        } else {

            return NSURLSessionAuthChallengePerformDefaultHandling;

        }

    }];

}


@end

確保應(yīng)用程序委托保存完成處理程序(根據(jù)需要實(shí)例化后臺(tái)會(huì)話):


- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

    NSAssert([[BackgroundSessionManager sharedManager].session.configuration.identifier isEqualToString:identifier], @"Identifiers didn't match");

    [BackgroundSessionManager sharedManager].savedCompletionHandler = completionHandler;

}

然后開始下載:


for (NSString *filename in filenames) {

    NSURL *url = [baseURL URLByAppendingPathComponent:filename];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    [[[BackgroundSessionManager sharedManager] downloadTaskWithRequest:request progress:nil destination:nil completionHandler:nil] resume];

}

請(qǐng)注意,我不提供任何與任務(wù)相關(guān)的塊,因?yàn)樗鼈兣c后臺(tái)會(huì)話不可靠。(即使在應(yīng)用終止后,背景下載仍會(huì)繼續(xù)進(jìn)行,并且這些功能塊早已消失。)人們必須依靠會(huì)話級(jí)別,并且setDownloadTaskDidFinishDownloadingBlock只能輕松地重新創(chuàng)建。


顯然,這是一個(gè)簡(jiǎn)單的示例(僅一個(gè)后臺(tái)會(huì)話對(duì)象;僅使用URL的最后一個(gè)組件作為文件名將文件保存到docs文件夾中;等等),但希望它能說明這種模式。


查看完整回答
反對(duì) 回復(fù) 2019-11-26
?
寶慕林4294392

TA貢獻(xiàn)2021條經(jīng)驗(yàn) 獲得超8個(gè)贊

回調(diào)是否為塊應(yīng)該沒有任何區(qū)別。實(shí)例化an時(shí)AFURLSessionManager,請(qǐng)確保使用實(shí)例化它NSURLSessionConfiguration backgroundSessionConfiguration:。此外,請(qǐng)確保調(diào)用經(jīng)理setDidFinishEventsForBackgroundURLSessionBlock與你的回調(diào)塊-這就是你應(yīng)該寫通常NSURLSessionDelegate的方法定義的代碼: URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session。此代碼應(yīng)調(diào)用您的應(yīng)用程序委托的后臺(tái)下載完成處理程序。

關(guān)于后臺(tái)下載任務(wù)的一則建議-即使在前臺(tái)運(yùn)行時(shí),它們的超時(shí)也將被忽略,這意味著您可能會(huì)在沒有響應(yīng)的下載中“卡住”。這沒有記錄在任何地方,使我瘋了一段時(shí)間。第一個(gè)嫌疑人是AFNetworking,但即使直接調(diào)用NSURLSession之后,其行為也保持不變。

祝好運(yùn)!


查看完整回答
反對(duì) 回復(fù) 2019-11-26
?
狐的傳說

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超3個(gè)贊

AFURLSessionManager


AFURLSessionManager創(chuàng)建和管理的NSURLSession基于指定的對(duì)象上NSURLSessionConfiguration的對(duì)象,它符合<NSURLSessionTaskDelegate>,<NSURLSessionDataDelegate>,<NSURLSessionDownloadDelegate>,和<NSURLSessionDelegate>。


鏈接到此處的文檔


查看完整回答
反對(duì) 回復(fù) 2019-11-26
  • 3 回答
  • 0 關(guān)注
  • 916 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)