gpt4 book ai didi

ios - 使用 NSURLSession 时无法调用 didReceiveData

转载 作者:行者123 更新时间:2023-11-28 19:39:40 31 4
gpt4 key购买 nike

我正在从这个 React Native 模块中获取一些代码 react-native-file-upload .我正在尝试将其从使用 NSURLConnection(已弃用)更新为使用 NSURLSession 并报告上传进度。

我能够毫不费力地将代码从 NSURLConnection 切换到 NSURLSession,但我正在努力让 didReceiveData 委托(delegate)被调用。为什么不调用 didReceiveData 委托(delegate)?

这是我修改后的 FileUpload.m

#import <Foundation/Foundation.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <UIKit/UIKit.h>
#import <Photos/Photos.h>

#import "RCTBridgeModule.h"
#import "RCTLog.h"

@interface FileUpload : NSObject <RCTBridgeModule, NSURLSessionDataDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate>
@end

@implementation FileUpload

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(upload:(NSDictionary *)obj callback:(RCTResponseSenderBlock)callback)
{
NSString *uploadUrl = obj[@"uploadUrl"];
NSDictionary *headers = obj[@"headers"];
NSDictionary *fields = obj[@"fields"];
NSArray *files = obj[@"files"];
NSString *method = obj[@"method"];

if ([method isEqualToString:@"POST"] || [method isEqualToString:@"PUT"]) {
} else {
method = @"POST";
}

NSURL *url = [NSURL URLWithString:uploadUrl];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:method];

// set headers
NSString *formBoundaryString = [self generateBoundaryString];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", formBoundaryString];
[req setValue:contentType forHTTPHeaderField:@"Content-Type"];
for (NSString *key in headers) {
id val = [headers objectForKey:key];
if ([val respondsToSelector:@selector(stringValue)]) {
val = [val stringValue];
}
if (![val isKindOfClass:[NSString class]]) {
continue;
}
[req setValue:val forHTTPHeaderField:key];
}


NSData *formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData* reqBody = [NSMutableData data];

// add fields
for (NSString *key in fields) {
id val = [fields objectForKey:key];
if ([val respondsToSelector:@selector(stringValue)]) {
val = [val stringValue];
}
if (![val isKindOfClass:[NSString class]]) {
continue;
}

[reqBody appendData:formBoundaryData];
[reqBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
[reqBody appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
[reqBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}

// add files
for (NSDictionary *file in files) {
NSString *name = file[@"name"];
NSString *filename = file[@"filename"];
NSString *filepath = file[@"filepath"];
NSString *filetype = file[@"filetype"];

NSData *fileData = nil;

NSLog(@"filepath: %@", filepath);
if ([filepath hasPrefix:@"assets-library:"]) {
NSURL *assetUrl = [[NSURL alloc] initWithString:filepath];

__block NSData * tempData = nil;

PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[assetUrl] options:nil];
PHAsset *asset = result.firstObject;

if (asset)
{
PHCachingImageManager *imageManager = [[PHCachingImageManager alloc] init];

// Request an image for the asset from the PHCachingImageManager.
[imageManager requestImageForAsset:asset targetSize:CGSizeMake(100.0f, 100.0f) contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage *image, NSDictionary *info)
{
NSLog(@"IMAGE: %@", image);
tempData = UIImagePNGRepresentation(image);
}];
}
fileData = tempData;
} else if ([filepath hasPrefix:@"data:"] || [filepath hasPrefix:@"file:"]) {
NSURL *fileUrl = [[NSURL alloc] initWithString:filepath];
fileData = [NSData dataWithContentsOfURL: fileUrl];
} else {
fileData = [NSData dataWithContentsOfFile:filepath];
}

[reqBody appendData:formBoundaryData];
[reqBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name.length ? name : filename, filename] dataUsingEncoding:NSUTF8StringEncoding]];

if (filetype) {
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", filetype] dataUsingEncoding:NSUTF8StringEncoding]];
} else {
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", [self mimeTypeForPath:filename]] dataUsingEncoding:NSUTF8StringEncoding]];
}

[reqBody appendData:[[NSString stringWithFormat:@"Content-Length: %ld\r\n\r\n", (long)[fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];
[reqBody appendData:fileData];
[reqBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}

// add end boundary
NSData* end = [[NSString stringWithFormat:@"--%@--\r\n", formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
[reqBody appendData:end];

// send request
[req setHTTPBody:reqBody];

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:(id)self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"response status code: %ld", (long)[httpResponse statusCode]);
callback(@[[NSNull null], [NSString stringWithFormat:@"response status code: %ld", (long)[httpResponse statusCode]]]);
}];

[task resume];
}

- (NSString *)generateBoundaryString
{
NSString *uuid = [[NSUUID UUID] UUIDString];
return [NSString stringWithFormat:@"----%@", uuid];
}

- (NSString *)mimeTypeForPath:(NSString *)filepath
{
NSString *fileExtension = [filepath pathExtension];
NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL);
NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);

if (contentType) {
return contentType;
}
return @"application/octet-stream";
}


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

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSLog(@"didReceiveData");
}

@end

最佳答案

对于使用 NSURLSession 的委托(delegate)模式,我认为你应该通过这样的方式创建 NSURLSession:

[NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];

但不是:

[NSURLSession sharedSession];

我还注意到您的 NSURLSessionDataDelegate、NSURLSessionDelegate、NSURLSessionTaskDelegate 与 UIViewController 一起使用;但是,您的 NSURLSession 和委托(delegate)方法是在 FileUpload.m 中实现的。尝试编辑这一行:

@interface FileUpload : NSObject <RCTBridgeModule>

到:

@interface FileUpload : NSObject <RCTBridgeModule, NSURLSessionDataDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate>

然后创建没有完成处理程序的 NSURLSessionDataTask:

NSURLSessionDataTask *task = [session dataTaskWithRequest:req];

看看有没有区别。

关于ios - 使用 NSURLSession 时无法调用 didReceiveData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35240787/

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