2015-11-01 42 views
4

我在我的應用程序下面的方法,它使用NSURLSession從一個JSON格式的Web服務拉動的電影數據:試圖重構使用Singleton模式聯網方法的iOS

- (void) downloadMovieData { 

    //this is just a visual cue to show that processing is being done 
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 

    //creating the request 
    NSURL *url = [NSURL URLWithString:kMovieURL]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

    //creating the session 
    self.config = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    self.session = [NSURLSession sessionWithConfiguration:self.config]; 

    //the object that makes the call to the web service using the request and the session, and returns a response or an error 
    NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

     //At this point a response has been received, so we can turn the indicator off 
     [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; 

     //I am casting the response to an NSHTTPURLResponse so I can check the status code of the response 
     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 

     //a status code of 200 means a successful connection with the web service 
     if (httpResponse.statusCode == 200) { 

      dispatch_async(dispatch_get_main_queue(), ^{ 
       NSLog(@"Success!"); 
       //I send the data that was received from the response to the method so that the JSON data is extracted 
       [self populateArray:data]; 
      }); 

     } else { 
      NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
      NSLog(@"Received HTTP %ld: %@", (long)httpResponse.statusCode, result); 
     } 
    }]; 

    [task resume]; 

} 

- (void) populateArray: (NSData *)data { 

    NSError *jsonError; 
    NSDictionary *response =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError]; 

    if (response) { 
     self.movieObjects = response[@"movies"]; 
     NSLog(@"The movie objects are: %@", self.movieObjects); 
     [self.tableView reloadData]; 
    } else { 
     NSLog(@"ERROR: %@", jsonError); 
    } 
} 

上面的代碼工作正常。沒有問題。然而,現在我想要做的是重構我的代碼,以便在包含我的UITableView委託方法的類中包含所有網絡代碼,我希望將代碼移入單獨的類中,該類使用Singleton方法更好地分離的代碼。我對這個下面的框架代碼看起來像下面這樣:

#import "Networker.h" 

@implementation Networker 

+ (NSURLSession *)dataSession { 
    static NSURLSession *session = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 
    }); 
    return session; 
} 

+ (void)fetchContentsOfURL:(NSURL *)url completion:(void (^)(NSData *data, NSError *error)) completionHandler { 

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

     if (completionHandler == nil) return; 

     if (error) { 
      completionHandler(nil, error); 
      return; 
     } 
     completionHandler(data, nil); 
    }]; 

    [dataTask resume]; 
} 

我沒有問題理解Singleton類的。這不是問題。我的問題是理解如何理解這種方法的「完成處理」部分:

+ (void)fetchContentsOfURL:(NSURL *)url completion:(void (^)(NSData *data, NSError *error)) completionHandler {} 

我想這樣做,是移動,我在該方法中的代碼,「downloadMovieData」,到「fetchContentsOfURL」 ,然後返回一個NSData對象,然後我可以使用它填充我的調用類中的UITableView。然而,在這樣做的時候,我想確保我理解這種新方法的「completionHandler」部分發生了什麼。我怎樣才能做到這一點?

回答

1

你不能移動它,所以它返回,因爲它是異步的。技術上你可以,但是當你等待時,你會阻止主線程。

取而代之,您只需將當前代碼替換爲對單例的調用,並在完成塊中調用其他方法來處理他的數據。

幾件事情需要注意:

  1. 這是一個好主意,分派給主要在你的單身它叫人完成塊之前,所以你不需要功能的所有用戶記住要做
  2. 它並不需要是一個單身,你可以每個實例你需要它,或者使用依賴注入代替,這兩者通常提供更好的建築設計
+0

非常感謝您的時間類的副本回復。你能否在這種情況下解釋你的意思是「依賴注入」(即iOS)? – syedfa

+1

任何語言的依賴注入都是通過將這些值傳遞給它(注入它們)的地方來爲其提供一個類的過程,在這個類中,該類將會有代碼去執行,並從其他地方填充需求。 – Wain