我的问题是采用[NSURLConnection sendAsynchronousRequest...] with POST方法,在iOS7失败时失败,而在iOS6环境下成功。
其他资料:
有没有人能帮我或给我建议?非常感谢。
我的代码如下(更新为v3,成功)(谢谢Rob的回答)
- (void) apiLogin
{
NSDictionary *params = @{@"client_id" : @"1234567",
@"response_type" : @"token",
@"redirect_uri" : @"/oauth2-php/server/examples/pdo/",
@"state" : @"test_state",
@"scope" : @"",
@"accept" : @"Yep",
@"uid" : uid,
@"pwd" : withPwd};
NSData *postDataString = [self dataForHTTPPost:params];
// Server API 位置
NSURL *url=[NSURL URLWithString:@"http://xxx.xxx.tw/xxx.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:120];
[request setURL:url];
// Solution3:
NSString *postLength = [NSString stringWithFormat:@"%d", [postDataString length]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postDataString];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
NSLog(@"D1: responseCode: %d", responseCode);
if (!connectionError && responseCode == 200) {
// 採用Apple官方方法將 來源轉成JSON Format並交由NSDictionary 接手.
NSError *localError = nil;
NSLog(@"data:%@", data);
NSDictionary *allInDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&localError];
NSLog(@"Source:%@", allInDic);
NSLog(@"error:%@", localError);
// 取出oauth_token資料
if ([[allInDic objectForKey:@"status"] integerValue] == 200) {
// 將新取得之 oauth_token 寫入DB
NSArray * dataArray = [allInDic objectForKey:@"data"];
NSDictionary *responseData = [dataArray objectAtIndex:0];
NSString *t = [responseData objectForKey:@"oauth_token"];
[helper setDbOauthToken:nil :t :TABLE_USER_PROFILES];
NSLog(@"(API-New)oauth_token:%@", t);
} else
{
NSLog(@"connectionError=%@", connectionError);
NSLog(@"responseCode=%d", responseCode);
}
}
}];
}
- (NSData *)dataForHTTPPost:(NSDictionary*) parms
{
NSMutableArray *array = [NSMutableArray array];
for (NSString *key in parms) {
id obj = [parms objectForKey:key];
NSString *valueString;
if ([obj isKindOfClass:[NSString class]])
valueString = obj;
else if ([obj isKindOfClass:[NSNumber class]])
valueString = [(NSNumber *)obj stringValue];
else if ([obj isKindOfClass:[NSURL class]])
valueString = [(NSURL *)obj absoluteString];
else
valueString = [obj description];
[array addObject:[NSString stringWithFormat:@"%@=%@", key, valueString]];
}
NSString *postString = [array componentsJoinedByString:@"&"];
NSLog(@"New2a HTTPPost Data:%@", postString);
return [postString dataUsingEncoding:NSUTF8StringEncoding];
}
- (IBAction)loginAction:(id)sender {
[self apiLogin];
}下面是在iOS6上调试输出的代码
New2a HTTPPost Data:response_type=token&uid=xxx&accept=Yep&scope=&client_id=1234567&state=test_state&redirect_uri=/oauth2-php/server/examples/pdo/&pwd=xxx
D1: responseCode: 200
data:<7b227374 61747573 223a3230 302c2264 61746122 3a5b7b22 6f617574 685f746f 6b656e22 3a224870 47366546 4b304a37 38434343 54306352 506e4d77 62544d5c 2f455631 32793422 7d5d7d>
Source:{
data = (
{
"oauth_token" = "HpG6eFK0J78CCCT0cRPnMwbTM/EV12y4";
}
);
status = 200;
}
error:(null)
(API-New)oauth_token:HpG6eFK0J78CCCT0cRPnMwbTM/EV12y4下面是在iOS7上调试输出的代码
New2a HTTPPost Data:response_type=token&uid=&accept=Yep&scope=&client_id=1234567&state=test_state&redirect_uri=/oauth2-php/server/examples/pdo/&pwd=
D1: responseCode: 200
data:<>
Source:(null)
error:Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (No value.) UserInfo=0x8a28d90 {NSDebugDescription=No value.}
connectionError=(null)
responseCode=200谢谢你帮了我大忙,我的问题解决了。根路径在代码下面。在IOS6中,当没有输入"idField.txt“字段时,我可以获得uid/withPwd默认值。但是在iOS7中,这个代码不能用(uid/withPwd)获得默认值。谢谢罗伯,我的问题解决了。
NSString *uid = idField.text;
NSString *withPwd = pwdField.text;
// For testing Account ID
if (!uid||!withPwd) {
uid=@"xxx@gmail.com";
withPwd=@"xxxx";
}
NSLog(@"uid:%@ , pwd:%@", uid, withPwd);将问题代码更新到此,可以在iOS6 & iOS7上工作。
// For testing Account ID
if ([uid isEqualToString:@""] || [withPwd isEqualToString:@""] ) {
uid=@"xxx@gmail.com";
withPwd=@"xxxx";
}发布于 2013-10-07 18:43:30
您正在记录data,但您可能希望查看它的字符串表示形式。查看结果字符串,并从服务器查看该响应中的内容。这样,如果服务器失败并返回一些非JSON错误消息,您可以看到字符串是什么。
同样,如果connectionError不是nil,则可能需要记录它。这里的情况并非如此(否则,您就不会进入当前的NSLog,但如果不是nil,则可能值得考虑这一点)。因此:
if (!connectionError && responseCode == 200) {
// 採用Apple官方方法將 來源轉成JSON Format並交由NSDictionary 接手.
if (data)
NSLog(@"data string: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
else
NSLog(@"data is nil");
NSError *parseError = nil;
NSDictionary *allInDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
NSLog(@"Source:%@", allInDic);
NSLog(@"error:%@", parseError);
// 取出oauth_token資料
if ([allInDic[@"status"] integerValue] == 200) {
// 將新取得之 oauth_token 寫入DB
NSArray * dataArray = allInDic[@"data"];
NSDictionary *responseDictionary = dataArray[0];
NSString *t = responseDictionary[@"oauth_token"];
[helper setDbOauthToken:nil :t :TABLE_USER_PROFILES];
NSLog(@"(API-New)oauth_token:%@", t);
}
}
else
{
NSLog(@"connectionError=%@", connectionError);
NSLog(@"responseCode=%d", responseCode);
}我怀疑,一旦您查看了您的data的字符串表示,这个问题可能会变得不言自明。
顺便说一句,这不太可能是问题,但请确保您正在正确编码要添加到postData中的字符串。例如,如果您的密码包含一个符号、加号、空格或其他保留字符(如RFC2396第2.2节所述),则当前代码将无法工作。您可能希望将CFURLCreateStringByAddingPercentEscapes应用于添加到postData中的值,例如,您可以使用如下所示的NSString类别:
@implementation NSString (URLPostEncode)
- (NSString *)stringForHTTPPost
{
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)self,
(CFStringRef)@" ",
(CFStringRef)@";/?:@&=+$,",
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}
@end我个人将其与以下NSDictionary类别结合起来:
@implementation NSDictionary (URLPostEncode)
- (NSData *)dataForHTTPPost
{
NSMutableArray *array = [NSMutableArray array];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSString *valueString;
if ([obj isKindOfClass:[NSString class]])
valueString = obj;
else if ([obj isKindOfClass:[NSNumber class]])
valueString = [(NSNumber *)obj stringValue];
else if ([obj isKindOfClass:[NSURL class]])
valueString = [(NSURL *)obj absoluteString];
else
valueString = [obj description];
[array addObject:[NSString stringWithFormat:@"%@=%@", key, [valueString stringForHTTPPost]]];
}];
NSString *postString = [array componentsJoinedByString:@"&"];
return [postString dataUsingEncoding:NSUTF8StringEncoding];
}
@end有了这两个类别,我就可以做如下的事情:
NSDictionary *params = @{@"client_id" : client_id,
@"response_type" : response_type,
@"redirect_uri" : redirect_uri,
@"state" : state,
@"scope" : scope,
@"accept" : accept,
@"uid" : uid,
@"withPwd" : withPwd};
NSData *postData = [params dataForHTTPPost];发布于 2013-10-07 20:14:57
我建议修改缓存策略,看看这是否有帮助。
cachePolicy:NSURLRequestUseProtocolCachePolicy试着使用
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheDatahttps://stackoverflow.com/questions/19229491
复制相似问题