简体   繁体   English

NSURLConnection委托方法未被调用

[英]NSURLConnection delegate methods not being called

I'm trying to use the delegate methods of NSURLConnection. 我正在尝试使用NSURLConnection的委托方法。 The following methods are currently not being called: 目前尚未调用以下方法:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection;

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
//I also want to be able to use self-signed https urls

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace;
//I also want to be able to use self-signed https urls

I'm currently using a synchronous call but asynchronous seems better because after I complete the code base I'm going to implement it into an iPhone application and I can't have my ui freezing. 我目前正在使用同步调用,但异步似乎更好,因为在我完成代码库后,我将把它实现到iPhone应用程序中,我不能让我的ui冻结。

With the following method responseData = [NSMutableData dataWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]]; 使用以下方法responseData = [NSMutableData dataWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]];

I get back the data I need but using asynchronous I seems I have to use the delegate methods to get data back. 我得到了我需要的数据但是使用异步我似乎必须使用委托方法来获取数据。 I tried to add the delegate by using @interface myClass : NSObject<NSURLConnectionDelegate> 我尝试使用@interface myClass : NSObject<NSURLConnectionDelegate>添加委托

I'm calling my method as follows: 我正在调用我的方法如下:

-(void)grabData{
    NSArray* array = [NSArray arrayWithObjects:@"auth.login",@"user",@"pass", nil];
    NSData* packed_array = [array messagePack];

    NSURL* url = [NSURL URLWithString:@"https://192.168.1.115:3790/"];
    NSMutableURLRequest* request = [[[NSMutableURLRequest alloc]initWithURL:url]retain];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"RPC Server" forHTTPHeaderField:@"Host"];
    [request setValue:@"binary/message-pack" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d",[packed_array length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:packed_array];

    //NSHTTPURLResponse *response = nil;
    NSError *error = nil;

    NSLog(@"connecting");
    NSURLConnection* connection = [[[NSURLConnection alloc]initWithRequest:request delegate:self]retain];
    if (connection) {
        NSLog(@"connection exists");
        self.responseData = [[NSMutableData data]retain];
    }
    else {
        NSLog(@"Connection doesn't exist?");
    }
    NSLog(@"response data: %@",[responseData messagePackParse]);
    NSLog(@"error: %@",error);
}

I've attempted the following: 我尝试过以下方法:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];

I continued to search for related questions and found this answer most helpful . 我继续搜索相关问题,发现这个答案最有帮助 It lead me to using the following method. 它引导我使用以下方法。 First I declared a BOOL property called finished in my interface and added the following method in my implementation which caused my delegate methods to be called. 首先,我在我的界面中声明了一个名为finished的BOOL属性,并在我的实现中添加了以下方法,这导致我的委托方法被调用。

while(!finished) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

Just a thought- any chance you're using Automatic Reference Counting and the object that is creating the NSURLConnection is being deallocated between the time you call [connection start] and when the delegate methods should be called (ie, data has been received)? 只是一个想法 - 你使用自动引用计数的任何机会,并且在你调用[连接开始]和应该调用委托方法(即,已经收到数据)之间,正在释放创建NSURLConnection的对象?

Does anything maintain a reference to the object you're using to create the NSURLConnection? 有什么东西保持对您用来创建NSURLConnection的对象的引用吗?

Based on additional information, it does seem like this is a likely cause. 根据其他信息,这似乎是一个可能的原因。 You likely have code such as the following in your App Delegate (or another class you've created). 您可能在App Delegate(或您创建的其他类)中有以下代码。

MyClass *object = [[MyClass alloc] init];
[object grabData];

This is great- it instantiates an object and then tells that object to grab the data in question. 这很棒 - 它实例化一个对象,然后告诉该对象获取有问题的数据。 But, once grabData completes (and before the NSURLConnection returns data), object will be deallocated because nothing is holding on to it. 但是,一旦grabData完成(并且在NSURLConnection返回数据之前),对象将被释放,因为没有任何东西保留它。 To fix this: 解决这个问题:

  1. Create a property in your .h file (where you create the object) to hold onto your instance of MyClass. 在.h文件(创建对象的位置)中创建一个属性以保留MyClass的实例。

    @property (strong) MyClass *object; @property(强)MyClass *对象;

  2. Synthesize that property in your .m file 合成.m文件中的该属性

    @synthesize object; @synthesize对象;

  3. Rather than just creating your object, hold a reference to it: 而不是仅仅创建您的对象,保持对它的引用:

    MyClass *myClass = [[MyClass alloc] init]; MyClass * myClass = [[MyClass alloc] init];

    [myClass grabData]; [myClass grabData];

    self.object = myClass; self.object = myClass;

This will prevent your object from being deallocated by ARC. 这将阻止您的对象被ARC取消分配。

When you're totally done with the object (your NSURLConnection has returned data), you can set self.object = nil to get rid of that reference. 当你完成对象(你的NSURLConnection已经返回数据)时,你可以设置self.object = nil来摆脱那个引用。

You can use this: 你可以用这个:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest: request delegate:self startImmediately:NO];

[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

[connection start];

If you're having trouble you can do what I've done in the past and use synchronous requests like so: 如果你遇到麻烦,你可以做我过去做过的事情并使用同步请求,如下所示:

NSHTTPURLResponse *response = nil;
NSError *error = nil;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]

This will output the data you need, all you need to do for it to not lock up your UI is use a block (GCD): 这将输出您需要的数据,所有您需要做的就是不要锁定您的UI是使用块(GCD):

dispatch_queue_t downloadQueue = dispatch_queue_create("download queue", NULL);
dispatch_async(downloadQueue, ^{
  NSHTTPURLResponse *response = nil;
  NSError *error = nil;
  NSData *myData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]
  dispatch_async(dispatch_get_main_queue(), ^{
    // Handle your response data
  });
});

After establishing the connection just write below 建立连接后,请写下面

[connection start]; [连接开始]; your delegate method will be called. 你的委托方法将被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM