我有以下代码从服务器获取数据;
-(void)loginForFaceBook
{
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:@"https://www.googleapis.com/auth/plus.me"
clientID:@"27615...6qdi60qjmachs.apps.googleusercontent.com"
clientSecret:@"Fs8A...u2PH"
keychainItemName:@"OAuth2 Sample:
Google+"
delegate:self
finishedSelector:@selector(viewController:finishedWithAuth:error:)];
[[self navigationController] pushViewController:viewController
animated:YES];
}
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
if (error != nil) {
// Authentication failed (perhaps the user denied access, or closed the
// window before granting access)
NSLog(@"Authentication error: %@", error);
NSData *responseData = [[error userInfo] objectForKey:@"data"]; //
kGTMHTTPFetcherStatusDataKey
if ([responseData length] > 0) {
// show the body of the server's authentication failure response
// NSString *str = [[NSString alloc] initWithData:responseData
// encoding:NSUTF8StringEncoding];
// NSLog(@"%@", str);
}
// self.auth = nil;
} else {
// NSString *authCode = [NSString alloc]in;
NSMutableURLRequest * request;
request = [[NSMutableURLRequest alloc] initWithURL:[NSURL
URLWithString:@"http://api.kliqmobile.com/v1/tokens"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60] ;
NSLog(@"%@",auth);
NSLog(@"ho gya success %@ :::: %@ :::: %@", auth.accessToken,
auth.refreshToken, auth.code);
NSMutableURLRequest * response;
NSError * error;
request.URL = [NSURL URLWithString:@"http://api.kliqmobile.com/v1/tokens"];
NSString *post = [NSString stringWithFormat:@"
{\"token\":\"%@\",\"secret\":\"%@\",\"service\":\"%@\",\"handle\":\"%@\"}",
auth.accessToken,auth.code,@"google",nil];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded"
forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:postData];
error = nil;
response = nil;
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request
delegate:self];
[connection start];
}
我已经实现了NSURLConnection
委托方法,数据打印得很好
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
NSMutableURLRequest * response;
NSError * error;
NSLog(@"Did Receive Data %@", [[NSString alloc]initWithData:data
encoding:NSUTF8StringEncoding]);
NSMutableURLRequest * requestContacts;
requestContacts = [[NSMutableURLRequest alloc] initWithURL:[NSURL
URLWithString:@"http://api.kliqmobile.com/v1/contacts"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60] ;
[requestContacts setHTTPMethod:@"GET"];
[requestContacts setAllHTTPHeaderFields:headers];
error = nil;
response = nil;
NSData* data1 = [NSURLConnection sendSynchronousRequest:requestContacts
returningResponse:&response error:&error];
NSLog(@"WE GET THE REQUIRED TOKAN DATA %@ :: %@ :: %@", [[NSString alloc]
initWithData:data1 encoding: NSASCIIStringEncoding], error ,response);
}
但在那之后我的应用程序崩溃并且它发出以下错误;
[NSHTTPURLResponse release]:发送到解除分配的实例0xcb51070的消息。
请建议我如何做到这一点。
答案 0 :(得分:0)
有几点想法:
didReceiveData
方法的目的是什么?这里有很多问题:
您真的不应该在NSURLConnectionDataDelegate
方法中进行同步网络请求。
你根本不应该做同步请求,而是异步执行。
接收数据与创建此新请求之间的联系是什么?您没有在请求中使用数据,为什么要在此处执行此操作?
典型的模式是:
didReceiveResponse
应该在某个类属性中实例化NSMutableData
对象。
didReceiveData
的唯一功能应该是将收到的数据附加到NSMutableData
。注意,在收到所有数据之前,可以多次调用此方法。
在connectionDidFinishLoading
中,您应该在成功完成请求后启动后续步骤。如果您想在初始请求完成时启动另一个异步网络请求,请在此处执行此操作。
在didFailWithError
中,您显然可以处理连接失败。
致电connectionWithRequest
时,不应使用start
方法。对start
参数使用initWithRequest:delegate:startImmediately:
NO
时,仅使用startImmediately
。否则,连接会自动启动,您只能再次启动。
与原始问题无关,但您创建的post
字符串不正确。您错过了参数值。更好的是,不是手动创建JSON,而是使用NSDictionary
,然后使用NSJSONSerialization
从该字典中创建包含JSON的NSData
对象。这更安全:
NSDictionary *params = @{@"token" : auth.accessToken,
@"secret" : auth.code,
@"service" : @"google",
@"handle" : @""};
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
显然,为handle
值提供所需的一切。
与切片过程相关的观察,但我想知道您是否正在利用Xcode提供的所有功能。例如,您将response
声明为NSMutableURLRequest
,然后将其用作sendSynchronousRequest
的参数应生成编译器警告。你的stringWithFormat
字符串post
也是如此(我的第三点)。这应该也会产生警告。
这些都不是直接相关的,但我想知道你是否没有注意到任何其他编译时警告。编写健壮的代码时,这些警告是您最好的朋友,我建议您解决所有问题。为了更进一步,您还应该通过静态分析器运行项目("分析" on"产品"菜单,或 shift + 命令 + B ),并解决它指出的任何事情。