2013-11-14 49 views
9

我使用NSURLSession從資源庫上傳照片到服務器有一些問題。NSURLSession和流式上傳在後臺

起初NSURLSession不支持流式上傳。

@property (nonatomic, strong) NSURLSession *uploadSession; 

... 

_uploadSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration 
       backgroundSessionConfiguration:kUploadBackgroundURLSessionIdentifier] delegate:self delegateQueue:nil]; 

... 

NSURLSessionUploadTask *task = [self.uploadSession uploadTaskWithStreamedRequest:URLRequest]; 

這是一個例外:

Terminating app due to uncaught exception 'NSGenericException', reason: 'Upload tasks in background sessions must be from a file' 

這真是奇怪,因爲蘋果的手冊不包含有關使用僅uploadTaskWithRequest:fromFile:背景會話的任何信息,試圖利用當我得到了一個例外。如果我想要從素材資源庫中上傳真正龐大的視頻文件,該怎麼辦?我應該將它保存到我的tmp目錄嗎?

貌似唯一的原因就是反正用uploadTaskWithRequest:fromFile:吧?但是,接下來我有一個問題,即如果上傳過程中斷並開始在後臺上傳下一部分,服務器如何知道文件的哪部分內容正在上傳?

我應該爲此做些什麼?以前,如果我想繼續上傳先前啓動的部分文件,我在URL請求中使用了Content-Range。現在我不能那樣做 - 我必須在創建上傳任務之前創建一個URL請求,並且看起來像NSURLSession必須爲我自動執行類似操作嗎?

有人做過這樣的事嗎?由於

+2

當我閱讀文檔時,非常清楚您必須提供背景文件。不確定你的問題 - 如果文件只是部分上傳,並且你的服務告訴你它已經收到了多少,那麼你可以修剪你的文件並重新發送未發送的部分,不。我沒有這樣做的經驗,但似乎可行。 –

+0

是的,一切都看起來可行,但有一個問題,如果我想要從素材資源庫上傳一個巨大的視頻,我必須將它複製(如果我有足夠的空間)到我的應用程序文件夾,然後開始複製,然後從時間定時檢查已上傳的內容,修剪文件並開始新的請求。但是蘋果的文檔告訴我必須爲每個文件創建一個任務。 – gN0Me

+0

我對資產庫沒有經驗 - 什麼是您將用來檢索視頻的框架或類? –

回答

1

轉換爲NSData的複製並在app文件夾

ALAsset *asset = [cameraRollUploadImages objectAtIndex:startCount]; 
ALAssetRepresentation *representation = [asset defaultRepresentation]; 

// create a buffer to hold the data for the asset's image 
uint8_t *buffer = (Byte *)malloc(representation.size);// copy the data from the asset into the buffer 
NSUInteger length = [representation getBytes:buffer 
            fromOffset:0 
             length:representation.size 
             error:nil]; 

// convert the buffer into a NSData object, free the buffer after 
NSData *image = [[NSData alloc] initWithBytesNoCopy:buffer 
              length:representation.size 
             freeWhenDone:YES]; 
+6

是的,這正是我們正在做的。但是,如果用戶在AssetsLibrary中有一個巨大的視頻文件,則會出現問題 – gN0Me

0

現在寫的,沒有辦法otherthan保存照片到本地文件系統或臨時目錄。

以下代碼確保您的數據不會因exif標籤而丟失。 (ALAsset => NSData)

ALAssetRepresentation *assetRepresentation = [(ALAsset *)assetBeingUploaded defaultRepresentation]; 
uint8_t *buffer = (uint8_t *)malloc(sizeof(uint8_t)*[assetRepresentation size]); 
NSUInteger buffered = 0; 
if (buffer != NULL) 
buffered = [assetRepresentation getBytes:buffer fromOffset:0.0 length:assetRepresentation.size error:nil]; 
self.imageBeingUploaded = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES]; 

後臺會話中的上傳任務不支持完成處理程序。我們應該去,

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL; 

我懷疑我們如何得到響應報頭或身體的情況下,如果我們使用文件中使用的背景會話& uploadtask有要求嗎?

0

一個乾淨的解決方法是創建一個NSOperation,它將使用NSStream將資產庫中的文件複製到臨時文件夾中,以便在操作完成時您不會遇到大文件崩潰上傳該臨時文件,上傳完成後刪除它。

在我的情況下,我需要以多部分格式發送文件,因此臨時文件的創建是必要的,但我在20分鐘內上傳大文件,超過2GB,例如電影時遇到問題。

0

你不能在後臺上傳你需要上傳文件格式的NSData。您可以通過目錄路徑創建它