0

WebCalls というオブジェクト クラスをセットアップしました。このクラスでは、Web 呼び出しを行い、HTTPS サーバーから JSON を返します。メソッドが完全に機能するようになりました。テストしたところ、データは正常に返されます。ただし、私の問題は、クラス外で返されたデータにアクセスできないことです。

データを取得するコードは次のとおりです

インターフェース

@interface WebCall : NSObject{

    NSString *phoneNumber;
    NSString *jsonData;
}
@property (nonatomic, retain) NSMutableData *responseData;
@property (nonatomic, retain) NSString *jsonData;


-(void) getData: (NSString *) link;


@end

Implementation

@implementation WebCall

@synthesize jsonData;
@synthesize responseData;


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  [responseData setLength:0];
}   

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

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

    [responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    self.responseData = nil;
}


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

       NSString *s = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    jsonData = s;

}

-(void) getData: (NSString *) link{

        jsonData = [[NSString alloc] init];
self.responseData = [NSMutableData data];
    NSURL * url = [NSURL URLWithString:link];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPMethod:@"GET"];
    [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];

}



@end

インターフェイス クラスには、jsonData という文字列があります。プロパティと合成を使用して取得および設定します。したがって、Web 呼び出しを行った後、データを jsonData に割り当てます。Web 呼び出しクラスをインポートし、getInfo メソッドを使用して、jsonData を返してから、次を使用してアクセスできるはずです。

WebCall *wc = [[WebCall alloc] init];
[wc getData:url];
NSLog(@"%@", [c jsonData]);

ただし、これは null を出力するだけです。それでも、データを受信した後で Webcall クラスの String を出力すると、正常に出力されます。誰かが私が間違っていることを教えてもらえますか?

前もって感謝します

編集:完全な実装で更新

また、メソッド外の文字列にアクセスできません。コードを別のクラスにコピーし、JSON 文字列を割り当ててから、本体で再度呼び出してみましたが、再び null になります。その接続方法でしか印刷できないようです。次に、文字列をクリアするようです

編集:私が試したこと

[wc setWebCallDidFinish:^(NSString * json, NSString *test){

    NSLog(@"%@", json);


}];
[wc getData:@"12345"];
4

1 に答える 1

1

Adam jsonData が空の文字列である理由は、[[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES]; が原因です。つまり、新しいスレッドで実行され、ブロックされません。これは、[wc getData:url]; を呼び出すときを意味します。そしてすぐに NSLog(@"%@", [wc jsonData]); を呼び出します。http 要求はまだ完了しておらず、 - (void)connectionDidFinishLoading:(NSURLConnection *)connection デリゲート関数は WebCall でまだ呼び出されていません。

詳細な説明については、このiOS Concurrency Programming Guideを参照してください。基本的に、通知機能を WebCall に追加して、それを生成したオブジェクトにリクエストの読み込みが完了したことを通知できるようにする必要があります。私はそのようなブロックを使用します。


@interface WebCall : NSObject{

    NSString *phoneNumber;
    NSString *jsonData;
    void(^webCallDidFinish)(NSString *jsonData, id otherRandomVar);
}
@property (nonatomic, retain) NSMutableData *responseData;
@property (nonatomic, retain) NSString *jsonData;


-(void) getData: (NSString *) link;
-(void)setWebCallDidFinish:(void (^)(NSString *, id))wcdf;

@end

Implementation

@implementation WebCall

@synthesize jsonData;
@synthesize responseData;

-(void)setWebCallDidFinish:(void (^)(NSString *,id))wcdf{
    webCallDidFinish = [wcdf copy];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

       NSString *s = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    jsonData = s;
    webCallDidFinish(jsonData, @"any other object");

}
//all of your other code here

次に、呼び出しコードで次の


WebCall *wc = [[WebCall alloc] init];
[wc setWebCallDidFinish:^(NSString * json, id randomSecondVar) {
    NSLog(@"%@",json);
}];
[wc getData:url];

setWebCallDidFinish に指定したコード ブロックは、jsonData がロードされた後に呼び出されます。これを実現するためにデリゲート パターンを使用することもできます。この非同期リクエストがロードされている間、ユーザーに何らかのインジケータを提供する必要があることに注意してください。

于 2012-05-04T17:57:57.713 に答える