1

私の問題は、[NSURLConnection sendAsynchronousRequest...]withPOSTメソッドの採用が iOS7 で失敗し、iOS6 環境では成功することです。

その他の情報:

  1. 私のiOS6環境では、このようにサーバーからJSONデータを取得できます。(成功)

    {
        "status": 200,
        "data": [
            {
                "oauth_token": "BVgOa01tg6JvfuXOPoJS8wB26TpvAaDs"
            }
        ]
    }
    
  2. iOS7 で同じコードを実行すると、このエラー メッセージが表示されます。(失敗した)

    error:Error Domain=NSCocoaErrorDomain Code=3840 "The operation could not be completed. (Cocoa error 3840.)" (値なし)

  3. サーバー側の PHP コードを確認したところ、サーバーは iOS6 の POST データからデータを取得できますが、iOS7 からは POST データを取得できません。(同じコードの異なる結果、非常に奇妙です。)

誰かが私を助けたり、私に提案したりできますか? どうもありがとう。

私のコードは以下です(v3に更新され、成功しました)(ロブの回答に感謝します)

- (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";
}
4

2 に答える 2