gpt4 book ai didi

ios - NSURLSession - 使用带有 AWS IOS 开发工具包的 uploadTaskWithStreamedRequest

转载 作者:行者123 更新时间:2023-12-01 22:38:52 26 4
gpt4 key购买 nike

我已经搜索了几天来上传IOS Assets 而不在临时目录中创建文件副本的方法,但运气不好。我得到了使用临时副本的代码,但是复制可能从 10MB 到 4GB 的视频文件是不现实的。
我最接近以只读模式读取 Assets 的是下面的代码。根据苹果文档,这应该可以工作 - 请参阅以下链接:

https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html

我已启用这些键:

<key>com.apple.security.assets.movies.read-write</key>
<string>YES</string>
<key>com.apple.security.assets.music.read-write</key>
<string>YES</string>
<key>com.apple.security.assets.pictures.read-write</key>
<string>YES</string>
<key>com.apple.security.files.downloads.read-write</key>
<string>YES</string>

这是代码:
//  QueueController.h
#import <AVFoundation/AVFoundation.h>
#import <AWSS3.h>
#import <Foundation/Foundation.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "Reachability1.h"
#import "TransferType.h"
#import "TransferModel.h"
#import "Util.h"

@interface QueueController : NSObject<NSURLSessionDelegate>

@property(atomic, strong) NSURLSession* session;
@property(atomic, strong) NSNumber* sessionCount;
@property(atomic, strong) NSURLSessionConfiguration* configuration;

+ (QueueController*)sharedInstance;
- (void)transferMediaViaQueue:(MediaItem*)mediaItem
withTransferType:(TransferType)transferType;
@end

@implementation QueueController {
NSOperationQueue* copyQueue;
NSOperationQueue* transferQueue;
NSMutableArray* inProcessTransferArray;
NSMutableArray* pendingTransferArray;
bool isTransferring;
}

static QueueController* sharedInstance = nil;

// Get the shared instance and create it if necessary.
+ (QueueController*)sharedInstance {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[QueueController alloc] init];
}
}
return sharedInstance;
}

- (id)init {
if (self = [super init]) {
appDelegate =
(RootViewControllerAppDelegate*)[UIApplication sharedApplication]
.delegate;
copyQueue = [[NSOperationQueue alloc] init];
transferQueue = [[NSOperationQueue alloc] init];
transferQueue.maxConcurrentOperationCount = MAX_CONCURRENT_TRANSFERS;
inProcessTransferArray = [[NSMutableArray alloc] init];
pendingTransferArray = [[NSMutableArray alloc] init];
isTransferring = false;
if (self.session == nil) {
self.configuration = [NSURLSessionConfiguration
backgroundSessionConfigurationWithIdentifier:@"transferQueue"];
self.session = [NSURLSession sessionWithConfiguration:self.configuration
delegate:self
delegateQueue:transferQueue];
}
}
return self;
}

- (void)transferMediaViaQueue:(MediaItem*)mediaItem
withTransferType:(TransferType)transferType {
// Create a transfer model
NSUserDefaults* defaultUser = [NSUserDefaults standardUserDefaults];
NSString* user_id = [defaultUser valueForKey:@"UserId"];
TransferModel* transferModel = [[TransferModel alloc] init];
transferModel.mediaItem = mediaItem;
transferModel.transferType = transferType;
transferModel.s3Path = user_id;
transferModel.s3file_name = mediaItem.mediaName;
transferModel.assetURL =
[[mediaItem.mediaLocalAsset defaultRepresentation] url];

ALAssetRepresentation* mediaRep =
[mediaItem.mediaLocalAsset defaultRepresentation];
transferModel.content_type =
(__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(
(__bridge CFStringRef)[mediaRep UTI], kUTTagClassMIMEType);

@synchronized(pendingTransferArray) {
if ((!isTransferring) &&
(transferQueue.operationCount < MAX_CONCURRENT_TRANSFERS)) {
isTransferring = true;
if (transferModel.transferType == UPLOAD) {
/**
* Read ALAsset from NSURLRequestStream
*/
NSInvocationOperation* uploadOP = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(uploadMediaViaLocalPath:)
object:transferModel];
[transferQueue addOperation:uploadOP];
[inProcessTransferArray addObject:transferModel];
}

} else {
// Add to pending
[pendingTransferArray addObject:transferModel];
}
}
}

- (void)uploadMediaViaLocalPath:(TransferModel*)transferModel {
@try {
/**
* Fetch readable asset
*/
NSURL* assetURL =
[[transferModel.mediaItem.mediaLocalAsset defaultRepresentation] url];
NSData* fileToUpload = [[NSData alloc] initWithContentsOfURL:assetURL];
NSURLRequest* assetAsRequest =
[NSURLRequest requestWithURL:assetURL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
/**
* Fetch signed URL
*/
AWSS3GetPreSignedURLRequest* getPreSignedURLRequest =
[AWSS3GetPreSignedURLRequest new];
getPreSignedURLRequest.bucket = BUCKET_NAME;
NSString* s3Key = [NSString stringWithFormat:@"%@/%@", transferModel.s3Path, transferModel.s3file_name];
getPreSignedURLRequest.key = s3Key;
getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodPUT;
getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];

// Important: must set contentType for PUT request
// getPreSignedURLRequest.contentType = transferModel.mediaItem.mimeType;
getPreSignedURLRequest.contentType = transferModel.content_type;
NSLog(@"mimeType: %@", transferModel.content_type);

/**
* Upload the file
*/
[[[AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder]
getPreSignedURL:getPreSignedURLRequest]
continueWithBlock:^id(BFTask* task) {
NSURLSessionUploadTask* uploadTask;
transferModel.sessionTask = uploadTask;
if (task.error) {
NSLog(@"Error: %@", task.error);
} else {
NSURL* presignedURL = task.result;
NSLog(@"upload presignedURL is: \n%@", presignedURL);

NSMutableURLRequest* request =
[NSMutableURLRequest requestWithURL:presignedURL];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPMethod:@"PUT"];
[request setValue:transferModel.content_type
forHTTPHeaderField:@"Content-Type"];

uploadTask =
[self.session uploadTaskWithStreamedRequest:assetAsRequest];
[uploadTask resume];
}
return nil;
}];
} @catch (NSException* exception) {
NSLog(@"exception: %@", exception);
} @finally {
}
}

- (void)URLSession:(NSURLSession*)session
task:(NSURLSessionTask*)task
didSendBodyData:(int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
// Calculate progress
double progress = (double)totalBytesSent / (double)totalBytesExpectedToSend;
NSLog(@"UploadTask progress: %lf", progress);
}

- (void)URLSession:(NSURLSession*)session
task:(NSURLSessionTask*)task
didCompleteWithError:(NSError*)error {
NSLog(@"(void)URLSession:session task:(NSURLSessionTask*)task "
@"didCompleteWithError:error called...%@",
error);
}

- (void)URLSessionDidFinishEventsForBackgroundURLSession:
(NSURLSession*)session {
NSLog(@"URLSessionDidFinishEventsForBackgroundURLSession called...");
}

// NSURLSessionDataDelegate
- (void)URLSession:(NSURLSession*)session
dataTask:(NSURLSessionDataTask*)dataTask
didReceiveResponse:(NSURLResponse*)response
completionHandler:
(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
//completionHandler(NSURLSessionResponseAllow);
}

@end

但我收到此错误:
(void)URLSession:session task:(NSURLSessionTask*)task didCompleteWithError:error called...Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo=0x17166f840 {NSErrorFailingURLStringKey=assets-library://asset/asset.MOV?id=94F90EEB-BB6A-4E9D-B77E-CDD60173B60C&ext=MOV, NSLocalizedDescription=cancelled, NSErrorFailingURLKey=assets-library://asset/asset.MOV?id=94F90EEB-BB6A-4E9D-B77E-CDD60173B60C&ext=MOV}
userInfo: {
NSErrorFailingURLKey = "assets-library://asset/asset.MOV?id=94F90EEB-BB6A-4E9D-B77E-CDD60173B60C&ext=MOV";
NSErrorFailingURLStringKey = "assets-library://asset/asset.MOV?id=94F90EEB-BB6A-4E9D-B77E-CDD60173B60C&ext=MOV";
NSLocalizedDescription = cancelled;
}

在此先感谢您的帮助。

问候,
-J

最佳答案

关于使用 NSURLSessionUploadTask 的一些评论:

  • 如果您实现 didReceiveResponse ,您必须调用completionHandler .
  • 如果您调用uploadTaskWithStreamedRequestrequest 的文档参数警告我们:

    The body stream and body data in this request object are ignored, and NSURLSession calls its delegate’s URLSession:task:needNewBodyStream: method to provide the body data.



    所以你必须执行needNewBodyStream如果实现 NSInputStream基于请求。
  • 预先警告,但使用这样的基于流的请求会创建一个带有 "chunked" transfer encoding 的请求并不是所有的服务器都能处理。
  • 在代码中的某一时刻,您似乎尝试将 Assets 的内容加载到 NSData 中。 .如果你有这么大的 Assets ,你不能合理地将它加载到 NSData 中。目的。此外,这与使用 uploadTaskWithStreamedRequest 不一致。 .

    您要么需要创建 NSInputStream或从文件上传。
  • 您似乎正在使用 NSURLRequest 的 Assets URL .该 URL 应该是您的 Web 服务的 URL。
  • 使用图像选择器时,您可以访问两个 URL 键:媒体 URL(一个 file:// 用于电影的 URL,但不是图片)和资源库引用 URL(一个 assets-library:// URL)。如果您使用媒体 URL,则可以使用它来上传电影。但是您不能将 Assets 库引用 URL 用于上传目的。您只能将其与 ALAssetsLibrary 结合使用.
  • 关于ios - NSURLSession - 使用带有 AWS IOS 开发工具包的 uploadTaskWithStreamedRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30375348/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com