2014-10-03 2 views
7

이 블록에 문제가 있습니다. NSURLSession 블록 안에있는 데이터를 가져 오려고합니다.NSURLSession을 사용하여 블록에서 데이터를 가져 오는 방법은 무엇입니까?

여기

-(NSDictionary *) RetrieveData{ 

    NSURLSession * session = [NSURLSession sharedSession]; 
    NSURL * url = [NSURL URLWithString: self.getURL]; 
    dataList =[[NSDictionary alloc] init]; 

    NSURLSessionDataTask * dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

     self.json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 

    }]; 
    return self.dataList; 
    [dataTask resume]; 

} 

NSURLSession의 블록 내부의 데이터를 얻을 수 있나요 내 코드입니까?

+2

JSON을 블록 외부에서 사용하려고합니까? 이 블록은 비동기 적으로 실행되므로 JSON 구문 분석을 수행하는 블록이 실행되기 전에'[dataTask resume]'_well 다음에 나오는 라인을 사용하게됩니다. – Rob

+0

안녕하세요. @Rob 내 게시물을 업데이트합니다. 예, json이 블록에서 데이터를 가져 와서 내 메서드에서 반환하도록하고 싶습니다. – user3818576

+0

그렇지 않습니다. 다시 전달하려면 완료 블록 패턴을 사용해야합니다. – Rob

답변

23
-(void)getJsonResponse:(NSString *)urlStr success:(void (^)(NSDictionary *responseDict))success failure:(void(^)(NSError* error))failure 
{ 
    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURL *url = [NSURL URLWithString:urlStr]; 

    // Asynchronously API is hit here 
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url 
              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {    
               NSLog(@"%@",data); 
               if (error) 
                failure(error); 
               else {            
                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
                NSLog(@"%@",json); 
                success(json);            
               } 
              }]; 
    [dataTask resume]; // Executed First 
} 

호출이 :

[self getJsonResponse:@"Enter your url here" success:^(NSDictionary *responseDict) { 
     NSLog(@"%@",responseDict); 
    } failure:^(NSError *error) { 
     // error handling here ... 
}]; 
+0

와우! 고맙습니다! – user3818576

+0

최고 답장 형제. 나는 upvoted. – user3182143

+0

기꺼이 도와 드리겠습니다. –

1
NSURLSession *session = [NSURLSession sharedSession]; 
NSURL *url = [NSURL URLWithString:@"http://www.code-brew.com/projects/Instamigos/api/login.php?instagram_id=572275360&access_token=572275360.4c70214.57e0ecb1113948c2b962646416cc0a18&name=dpak_29&uuid=ios_1"]; 
// Asynchronously API is hit here 
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url 
             completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {  
              NSLog(@"%@",data); 
              // Executed when the response comes from server 

              // Handle Response here 
              NSDictionary * json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
              NSLog(@"%@",json); 
}]; 
[dataTask resume]; // Executed First 
+0

이미이 작업을 수행했지만 json의 데이터를 반환 할 수는 없습니다. Pls 내 업데이트 게시물을 참조하십시오. 내가 이것을 사용하면 성공적인 결과를 얻을 수 있습니다. – user3818576

+0

블록 안쪽에서 돌아올 수 없습니다. 다른 접근법이 필요해. 내가 블록을 사용하여 코드를 제공 할 수 있습니다 –

+0

다른 코멘트에 작성된 코드가 –

8

당신은 완료 블록을 사용한다, 예를 들면 :

다음
- (void)retrieveData:(void (^)(NSDictionary * dictionary))completionHandler { 
    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURL *url = [NSURL URLWithString: self.getURL]; 

    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 

     if (completionHandler) { 
      completionHandler(dictionary); 
     } 
    }]; 
    [dataTask resume]; 
} 

이 할 것 호출하는 방법

[self retrieveData:^(NSDictionary *dictionary) { 
    // you can use the dictionary here 

    // if you want to update UI or model, dispatch this to the main queue: 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // do your UI stuff here 
    }); 
}]; 

// but dont try to use the dictionary here, because you will likely 
// hit this line before the above block fires off, and thus the 
// dictionary hasn't been returned yet! 

을 당신은 완료를 이용한 비동기 메소드를 호출하고 블록 패턴이기 때문에 코드에서 완성 블록 패턴을 사용해야합니다.

+0

BTW, 블록은 인스턴스 변수가 아닌 _local_ 변수 (블록에 매개 변수로 전달됨)를 사용합니다. 또한 스타일 론적으로, 메소드는 항상 소문자로 시작합니다. 그래서 그것을 변경했습니다. – Rob

+0

와우! 나는 이것을위한 간단한 코드를 얻는다고 생각했다. 내가 게시 한 것을 먼저 검색하도록하겠습니다. 죄송합니다. 귀하의 코드에 익숙하지 않습니다. – user3818576

+1

걱정하지 마십시오. 패턴에 익숙해 지려면 시간이 좀 걸립니다. 그러나 Cocoa API의 모든 곳에서 볼 수 있기 때문에 팔 주위를 두 드리는 것이 중요합니다."completion"또는 "completionHandler"라는 매개 변수를 볼 때마다 그것은 항상 나중에/비동기 적으로 호출되며 "다시 전달"하려는 경우 일반적으로 자체 완료 블록 패턴을 구현해야합니다. – Rob

3

당신은해야이 방법의 주위에 당신의 머리를 얻을 수 있습니다. 가장 좋은 방법은 RetrieveData (여기에서 코코아 명명 규칙을 위반 함)에서 메소드 이름을 startRetrievingData로 변경하는 것입니다. 최악의 경우 몇 분이 걸릴 수 있고 사용자가 당신을 싫어할 수 있기 때문에 실제로 데이터를 검색하는 메소드를 작성할 수 없습니다.

startRetrievingData를 호출하여 void를 반환하고 데이터가 검색 될 때 나중에 호출 될 때와 오류가 발생했을 때 나중에 호출 될 두 블록을 전달합니다. 데이터를 가져올 수 없습니다.

을 반환 할 수 없습니다. 데이터입니다. "데이터를 반환하는 방법"을 묻지 마십시오. 그렇게 할 수 없습니다. 데이터를 사용할 수있을 때 호출되는 블록에 코드를 제공하고 블록이 원하는 모든 작업을 담당하는 블록을 제공합니다.

+0

와우! 조언 해 주셔서 감사합니다. 정말 감사. 나는 코드 외에도 새로운 것을 배웠다. – user3818576