0

URL test.com/test.cfm にアクセスすると、次のように出力できます。

{"COLUMNS":["OBJID","USERNAME","USERPASSWORD","USERFNAME","USERMI","USERLNAME","COMPANY","TBLCOMPANYID","TBLTITLE","USERADDRESS1","USERADDRESS2","USERCITY","USERSTATE","USERZIP","USERSIGNATUREFILE","USERBUSINESSNUMBER","USERBUSINESSEXT","USERFAXNUMBER","USERCELLNUMBER","USEROTHERNUMBER","USEREMAIL1","USEREMAIL2","USEREMAIL3","DEFAULTPROJECTID","SIGNATURE","SIGNATUREUPLOADBY","SORTORDER","DISABLESTATUS","UUID","SITEID","PROGRAMID"],
"DATA":[[1,"test",11214.0,"admin","","admin","adf Inc.",1,1,"admin","","","California","","","",null,"","","","admin@test.com","","",0,null,null,0,false,"468373c5-1234-1234-1234-3133a2bb1679",62,1]]}

これを繰り返すには、まずこれを使用してデータを取得する必要がありますか?

NSMutableData *receivedData;
    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL     URLWithString:@"test.com/test.cfm"]
                                          cachePolicy:NSURLRequestUseProtocolCachePolicy
                                      timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:receivedData];
if (theConnection) {
    // Create the NSMutableData to hold the received data.
    // receivedData is an instance variable declared elsewhere.        
    NSLog(@"test = %@",receivedData);
} else {
    // Inform the user that the connection failed.
} 

私は正しい軌道に乗っていますか?出力は null と表示されます...

4

1 に答える 1

1

には何も割り当てていませんreceivedData。それはnil(ARCの下で)またはそうでないかもしれない未定義の値nil(非ARCの下で)のどちらかです。URL 接続を開始するために使用できるオブジェクトを作成しましたが、何もしていません。NSURLまた、URI スキーム (つまり、http://) の指定に失敗したため、valid を取得していない可能性もあります。

おそらく最も簡単な方法は (少なくとも iOS 5 および/または OS X v10.7 を前提として) を使用NSURLConnection+sendAsynchronousRequest:queue:completionHandler:NSJSONSerialization結果を解析することです。例えば

NSURLRequest *theRequest = 
            [NSURLRequest 
                 requestWithURL:[NSURL URLWithString:@"http://test.com/test.cfm"]
                    cachePolicy:NSURLRequestUseProtocolCachePolicy
                timeoutInterval:60.0];

// or just use [NSURLRequest requestWithURL:[NSURL ...]], since the
// protocol cache policy and a 60s timeout are the default values anyway

[NSURLConnection
   sendAsynchronousRequest:theRequest
   queue:[NSOperationQueue mainQueue]
   completionHandler:
        ^(NSHTTPURLResponse *urlResponse, NSData *data, NSError *error)
        {
            // catch all for connection errors...
            if(
                (urlResponse.statusCode < 200) ||
                (urlResponse.statusCode >= 300) || // bad status code, e.g. 404
                error || // error is non-nil would imply some other error
                ![data length] // data returned was empty
             )
             {
                  // report some sort of connection error
                 return;
             }

             NSError *jsonError = nil;
             id <NSObject> returnedJSONObject =
                [NSJSONSerialization
                          JSONObjectWithData:data options:0 error:&jsonError];
             if(jsonError)
             {
                   // server returned unintelligible JSON...
                   return;
             }

             NSLog(@"Got object %@", returnedJSONObject);

             // then, e.g.
             if(![jsonObject isKindOfClass:[NSDictionary class]])
             {
                 // server didn't return a dictionary
                 return;
             }

             NSArray *columns = [jsonObject objectForKey:@"COLUMNS"];
             if(![columns isKindOfClass:[NSArray class]])
             {
                  // server returned no COLUMNS object, or that
                  // object wasn't an array
                  return;
             }

             NSLog(@"columns are %@", columns);

             /* etc, etc */
        }];

自動化する方法が見つからない場合、クラスタイプのチェックはすぐに非常に面倒になりますが、それはすべて、質問に直接関係のない検証に関するものです。

上記が達成することは、URL のコンテンツに対する非同期 (つまり、非ブロッキング) 要求を送信することです。結果はメイン キュー (つまり、通常ユーザーとの対話を行うのと同じ場所) に蓄積されます。HTTP 操作全体が完了すると、最後に指定したコードが呼び出され、応答が検証および解析されます。これは同期的に行われるためブロックされますが、プロファイリングで心配する価値があることが示されない限り、心配する必要はありません。

ビルトイン パーサーが JSON に使用され、'Got object' に至るまでのすべてが、フェッチと解析が成功したことを確認するだけです。それは完全ではないかもしれません — 他にうまくいかないかもしれない何かを思いつくことができるなら、私が故意にそれを無視したと思い込まないでください.

その時点で、未知の型のオブジェクトしかありませんが、JSON の基礎により、通常は辞書または配列になります。したがって、コード例では、それが実際に辞書であることをテストしてから、通常のNSDictionaryインターフェイスを使用して「COLUMNS」キーのオブジェクトを取得します。配列を呼び出そうとするとobjectForKey:、配列はそのメソッドを実装していないため、例外が発生します。

次に、コードは、'COLUMNS' として保存されたオブジェクトが配列であることを確認します。JSON ルールによれば、それは別の辞書、文字列、またはその他のいくつかのいずれかである可能性があります。おそらく興味深いのはisKindOfClass:、オブジェクトが見つかったことと、それが配列であったことを 1 回の呼び出しでテストするコード呼び出しです。に任意のメッセージを送信することは明示的に許可されてnilおり、結果は常に になりnil、BOOL NO と同じように見えるため、これは機能します。

于 2012-10-30T22:33:05.813 に答える