我看了NSURLConnection doesn't call delegate methods,NSURLConnection didReceiveData not called等等,但我无法找到解决问题的方法。我已经验证我的URL有效,并且我能够使用常规nsurlconnection但不使用委托方法接收数据。
我已经设置了导入操作,但我的委托方法没有被调用。经过一些调试和研究后,我意识到nsurlconnection没有在主线程上运行,我相信这就是为什么我的委托方法没有被调用。我不知道还有什么可以尝试的。我很感激帮助。
我的导入类
#import "importOperation.h"
@interface importOperation ()<NSURLConnectionDelegate>
@property (nonatomic, strong) NSURL* url;
@property (nonatomic, strong) NSURLConnection* connection;
@property (nonatomic, strong) NSMutableData* buffer;
@property (nonatomic) long long int expectedContentLength;
@property (nonatomic, readwrite) NSError* error;
@property (nonatomic) BOOL isExecuting;
@property (nonatomic) BOOL isConcurrent;
@property (nonatomic) BOOL isFinished;
@end
@implementation importOperation
-(id)initWithURL:(NSURL *)url
{
self = [super init];
if (self) {
self.url = url;
}
return self;
}
-(void)start
{
NSURLRequest * request = [NSURLRequest requestWithURL:self.url];
self.isExecuting = YES;
self.isConcurrent = YES;
self.isFinished = NO;
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
}];
}
#pragma mark NSURLConnectionDelegate
-(NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{
return request;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
self.expectedContentLength = response.expectedContentLength;
self.buffer = [NSMutableData data];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.buffer appendData:data];
self.progressCallback(self.buffer.length / (float)self.expectedContentLength);
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {// implemented}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.data = self.buffer;
self.buffer = nil;
self.isExecuting = NO;
self.isFinished = YES;
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{// implemented}
- (void)setIsExecuting:(BOOL)isExecuting
{// implemented}
- (void)setIsFinished:(BOOL)isFinished
{// implemented}
- (void)cancel
{// implemented}
@end
这就是我调用导入操作的方式
-(void)getStuff:(void(^) (NSArray *result, NSError *error))completion
{
__block importOperation *anImportOperation = nil;
void(^completionBlock)(void)= ^(void){
NSData * importOperationData = [anImportOperation data];
NSError * error;
NSDictionary * jsonDictionary = [NSJSONSerialization JSONObjectWithData:importOperationData options:NSJSONReadingMutableContainers error:&error];
NSLog(@"parse data %@",jsonDictionary);
completion([jsonDictionary objectForKey:@"data"],error);
};
anImportOperation =[[importOperation alloc]initWithURL:[ServiceManager baseURLWithResource:@"beers"]];
[anImportOperation setCompletionBlock:completionBlock];
[self.operationQueue addOperation:anImportOperation];
if ([NSThread isMainThread] ==YES) {
completionBlock();
}
else{
dispatch_sync(dispatch_get_main_queue(),completionBlock);
}
这是日志声明
2014-12-22 23:42:58.430 Cheers[4736:621077] requested string https://api.brewerydb.com/v2/beers?key=APIKE
2014-12-22 23:42:58.456 Cheers[4736:621076] Is NOT main thread
2014-12-22 23:42:58.520 Cheers[4736:621136] PATH TO SQL STORE /Users/bla/Library/Developer/CoreSimulator/Devices/817B8B49-6316-40BD-ABF1-98C34FFD9299/data/Containers/Data/Application/252FA241-CE21-4C0E-A4DB-32D3DECC9DFB/Documents/CheersDataModel.sqlite
2014-12-22 23:42:58.647 Cheers[4736:620751] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
*** First throw call stack:
(
0 CoreFoundation 0x000000010dc72f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010d90bbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010dc72e6d +[NSException raise:format:] + 205
3 Foundation 0x000000010d5b01bf +[NSJSONSerialization JSONObjectWithData:options:error:] + 67
4 Cheers 0x000000010d006396 __27-[ServiceManager getBeers:]_block_invoke + 118
5 libdispatch.dylib 0x00000001105107f4 _dispatch_client_callout + 8
6 libdispatch.dylib 0x00000001104fbec9 _dispatch_barrier_sync_f_slow_invoke + 275
7 libdispatch.dylib 0x00000001105107f4 _dispatch_client_callout + 8
8 libdispatch.dylib 0x00000001104f98fb _dispatch_main_queue_callback_4CF + 949
9 CoreFoundation 0x000000010dbdafe9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
10 CoreFoundation 0x000000010db9deeb __CFRunLoopRun + 2043
11 CoreFoundation 0x000000010db9d486 CFRunLoopRunSpecific + 470
12 GraphicsServices 0x00000001121739f0 GSEventRunModal + 161
13 UIKit 0x000000010e2a2420 UIApplicationMain + 1282
14 Cheers 0x000000010d009153 main + 115
15 libdyld.dylib 0x0000000110545145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
答案 0 :(得分:2)
您的importOperationData
是nil
,这就是它崩溃的原因。您需要验证从服务器返回的值。
NSData * importOperationData = [anImportOperation data];
NSError * error;
if(importOperationData)
{
NSDictionary * jsonDictionary = [NSJSONSerialization JSONObjectWithData:importOperationData options:NSJSONReadingMutableContainers error:&error];
if(jsonDictionary)
{
completion([jsonDictionary objectForKey:@"data"],error);
}
}
答案 1 :(得分:0)
您正在从非主线程开始请求,因为您正在继承NSOperation
并将其添加到某些self.operationQueue
,这可能不主队列。< / p>
但问题是,在将操作添加到队列后调用完成块。删除此代码:
if ([NSThread isMainThread] ==YES) {
completionBlock();
}
else{
dispatch_sync(dispatch_get_main_queue(),completionBlock);
}