NSURLSessionUploadTask를 사용하여 백그라운드 세션에서 실행할 수있는 PUT을 통해 콘텐츠를 AWS S3에 업로드해야합니다.NSURLSession backgroundSession 완료시 추가 API 호출
지금까지 훌륭했습니다. 그러나 S3 로의 업로드가 완료되면 상태를 변경하기 위해 완료되면 API를 호출해야합니다.
S3 요청을 생성하려면 AWSS3을 입력 한 다음 this SO answer에 따라 NSURLSessionUploadTask에 복사합니다. 이것은 포 그라운드와 백그라운드에서 실행되며 파일을 S3에 업로드합니다.
이제 도움이 필요한 부분입니다. 나는 URLSession : task : didCompleteWithError 및 URLSessionDidFinishEventsForBackgroundURLSession 대리자 메서드를 사용하여 추가 API 요청을 호출하고, 표준 데이터 작업과 백그라운드에서 요청을 실행하지 않는 다운로드 작업을 모두 사용했습니다. 다시 앱을 엽니 다. 이상적으로 나는 그들이 즉시 발사하기를 바랄 것이다. 그들은 업로드의 화재가 포 그라운드에 있습니다. 나는 Wunderlist가 그들이 백그라운드에서하는 것을 정확하게하고있는 것을 보았다, 그들이 그것을 어떻게하는지에 관해 명확히하지 않는다.
다음은 내가 지금까지 가지고있는 것입니다. 어떤 도움이나 제안도 훌륭 할 것입니다. 이것이 나를 미치게합니다! :)
- (IBAction)upload:(id)sender {
AmazonS3Client *s3Client = [[AmazonS3Client alloc] initWithAccessKey:@"ABC" withSecretKey:@"123"];
NSString *identifier = [NSString stringWithFormat:@"com.journeyhq.backgroundSession.%@-%@", @"S3", @"ATTACHMENT_REMOTE_ID"];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"img.jpg"];
NSURL *fromFile = [NSURL fileURLWithPath:filePath isDirectory:NO];
S3PutObjectRequest *s3Request = [[S3PutObjectRequest alloc] initWithKey:[[NSString stringWithFormat:@"%@__%@__%@", @"ATTACHMENT_ID", @"ATTACHMENT_UUID", @"img.jpg"] lowercaseString] inBucket:@"BUCKET_NAME"];
s3Request.cannedACL = [S3CannedACL publicReadWrite];
NSMutableURLRequest *request = [s3Client signS3Request:s3Request];
NSString *urlString = [NSString stringWithFormat:@"https://%@.%@/%@", @"BUCKET_NAME", @"s3-eu-west-1.amazonaws.com", [[NSString stringWithFormat:@"%@__%@__%@", @"ATTACHMENT_ID", @"ATTACHMENT_UUID", @"img.jpg"] lowercaseString]];
request.URL = [NSURL URLWithString:urlString];
NSMutableURLRequest *request2 = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request2 setHTTPMethod:@"PUT"];
[request2 setAllHTTPHeaderFields:[request allHTTPHeaderFields]];
[request2 setValue:@"BUCKET_NAME.s3-eu-west-1.amazonaws.com" forHTTPHeaderField:@"Host"];
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request2 fromFile:fromFile];
[uploadTask resume];
}
#pragma - NSURLSessionTaskDelegate
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
dispatch_async(dispatch_get_main_queue(), ^{
self.progressView.progress = (float)totalBytesSent/(float) totalBytesExpectedToSend;
});
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSURLSessionConfiguration *sessionConfig = [session configuration];
NSString *identifier = [sessionConfig identifier];
NSLog(@"**identifier**: %@", identifier);
NSArray *identifierComponents = [identifier componentsSeparatedByString:@"."];
NSString *lastComponent = [identifierComponents lastObject];
NSArray *components = [lastComponent componentsSeparatedByString:@"-"];
NSString *sessionType = [components firstObject];
NSString *attachmentID = [components lastObject];
NSLog(@"sessionType: %@", sessionType);
NSLog(@"attachmentID: %@", attachmentID);
if (error == nil)
{
NSLog(@"Task %@ completed successfully", task);
if ([sessionType isEqualToString:@"S3"]) {
NSString *downloadIdentifier = [NSString stringWithFormat:@"com.journeyhq.backgroundSession.%@-%@", @"s3Completion", attachmentID];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:downloadIdentifier];
NSURLSession *downloadSession = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSString *urlString = @"API_COMPLETION_URL";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
NSURLSessionDownloadTask *downloadTask = [downloadSession downloadTaskWithRequest:request];
[downloadTask resume];
}
}
else
{
NSLog(@"Task %@ completed with error: %@", task,
[error localizedDescription]);
}
task = nil;
}
AppDelegate.h
- (void)application:(UIApplication *)application
handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)())completionHandler {
}
편집은 또한 다음을 시도했다. 이전과 같이 생성 된 작업은 작업을 다시 시작할 때 여전히 실행되지 않습니다.
- (void)application:(UIApplication *)application
handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)())completionHandler {
NSDictionary *userInfo = @{
@"completionHandler" : completionHandler,
@"sessionIdentifier" : identifier
};
[[NSNotificationCenter defaultCenter]
postNotificationName:@"BackgroundTransferNotification"
object:nil
userInfo:userInfo];
}
그런 다음 응용 프로그램은 당신이 될 것 같지 않습니다 AppDelegate에, 그것을 처리해야합니다 실행되지 않은 상태에서 백그라운드 작업이 완료되면 뷰 컨트롤러
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(handleBackgroundTransfer:)
name:@"BackgroundTransferNotification"
object:nil];
}
- (void)handleBackgroundTransfer:(NSNotification *)notification {
// handle the API call as shown in original example
...
}
답장을 보내 주셔서 감사합니다. 애플 리케이션 델리게이트 내부에 직접 있지는 않지만, 뷰 컨트롤러에서 처리되는 handleEventsForBackgroundURLSession 내에서 트리거 된 알림을 통해 이전에 시도한 적이 있습니다. 불행히도 그 결과는 같았습니다. 그것은 비록 내가 응용 프로그램을 열고 다음 작업을 실행하지 않는 한, 작업에 대한 이력서를 호출에도 불구하고, 그냥 화재가 발생하지 않는 작업을 만듭니다. handleEventsForBackgroundURLSession에서 직접 시도했지만 여전히 실행되지 않습니다. –
앱 위임 방법으로 시도한 코드를 게시 할 수 있습니까? –
혹시이 문제를 해결 했습니까? 나는 똑같은 문제를 겪고있다. – d0n13