0
我有一個名爲APICalls的類,它管理對API的調用。每個View Controller都會調用相應的方法(createUsername,getStates ...)並傳遞所需的參數。當數據被接收和解析時,它會回調視圖控制器以更新下載的信息的UI。下面的代碼正在工作,但我想知道是否有一個更簡單或更靈活/適當的方式來做到這一點,特別是當我更新視圖控制器中的用戶界面時。也許有協議和代表?歡迎任何建議。對後臺線程執行操作並從不同類更新UI
-(void) getObjects:(id)returnObject ofClass:(Class)returnClass fromUrl:(NSString *)urlString withPost:(NSString *)post orPut:(NSString *)put token:(NSString *)token callName:(NSString *)call andAlertTitle:(NSString *)alertTitle
{
// NSString *className = NSStringFromClass([object class]);
__block NSObject *object = returnObject;
__block Class class = returnClass;
__block NSMutableArray *array = [[NSMutableArray alloc]init] ;
__block BOOL dataReceived = NO;
[SVProgressHUD showWithStatus:@"Connecting to the server"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
ServerConnection *sc = [[ServerConnection alloc] init]; //post/get/put
NSDictionary *jsonDict;
if (([post isEqualToString:@""] || !post) && ([put isEqualToString:@""] || !put))
jsonDict = [sc getFromUrl:urlString withToken:token];
else if ([put isEqualToString:@""] || !put)
jsonDict = [sc postToUrl:urlString withPost:post andToken:token];
else
jsonDict = [sc putToUrl:urlString withPut:put andToken:token];
if (jsonDict)
{
NSLog(@"API: json received");
//parse the received json
NSObject *data = [self parseJson:jsonDict alertTitle:alertTitle];
if ([data isKindOfClass:[NSArray class]]) {
NSLog(@"API: Array");
dataReceived = YES;
// Iterate through the array of dictionaries
for(NSDictionary *dict in (NSArray *) data) {
object = [[class alloc] initWithJSONDictionary:dict];
[array addObject:object];
}
}
else if ([data isKindOfClass:[NSDictionary class]]){
NSLog(@"API: Dictionary");
dataReceived = YES;
object = [[class alloc] initWithJSONDictionary:(NSDictionary *)data];
if ([array count]> 0)
[array addObject:object];
}
else
NSLog(@"API: Error from API"); //alertview is shown from HandleError class
}
else{
NSLog(@"no json received");
dispatch_async(dispatch_get_main_queue(), ^(void){
[self alertStatus:@"Error when connecting to the server, please try it again" :alertTitle];
});
}
if (dataReceived)
{
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[SVProgressHUD dismiss];
if ([call isEqualToString:@"getStates"])
{
if ([self.currentViewController isKindOfClass:[SignUpViewController class]])
{
SignUpViewController *signup = (SignUpViewController *) self.currentViewController;
[signup updateStatesList:array];
}
else if ([self.currentViewController isKindOfClass:[MyProfileViewController class]])
{
MyProfileViewController *profileVC = (MyProfileViewController *) self.currentViewController;
[profileVC updateStatesList:array];
}
}
else if ([call isEqualToString:@"getPoints"])
{
PromotionSelectionViewController *promotionVC = (PromotionSelectionViewController *) self.currentViewController;
[promotionVC updatePoints:object];
}
else if ([call isEqualToString:@"getPromotions"])
{
PromotionSelectionViewController *promotionVC = (PromotionSelectionViewController *) self.currentViewController;
[promotionVC updatePromotionsList:array];
}
});
}
});
}
//CreateUser: creates an user when this sign up
-(void)createUserWithUsername:(NSString *)username name:(NSString *)name surname:(NSString *)surname birthdate:(NSString *)birthdate address:(NSString*) address city:(NSString *)city state:(int)state country:(int)country zipCode:(int)zipCode email:(NSString *)email password:(NSString *)password fromViewController:(UIViewController *)currentViewController
{
self.currentViewController = currentViewController;
//Create the post with the username and password
NSString *post =[[NSString alloc] initWithFormat:@"username=%@&name=%@&surname=%@&address=%@&city=%@&state=%d&country=%d&zipcode=%d&birthdate=%@&email=%@&password=%@&",username, name, surname, address, city, state, country, zipCode, birthdate,email,password];
NSLog(@"post: %@", post);
User *user;
[self getObjects:user ofClass:NSClassFromString(@"User") fromUrl:signupURL withPost:post orPut:nil token:nil callName:@"createUser" andAlertTitle:@"SignUp Failed"];
}
-(void) getPointsWithToken:(NSString *)token fromViewController:(UIViewController *)currentViewController{
self.currentViewController = currentViewController;
[self getObjects:nil ofClass:nil fromUrl:getPointsURL withPost:nil orPut:nil token:token callName:@"getPoints" andAlertTitle:@"Get Proints Number Failed"];
}
-(void)getStatesforCounry:(int)idCountry fromViewController:(UIViewController *) currentViewController
{
self.currentViewController = currentViewController;
NSString *url = [NSString stringWithFormat:@"%@%d", getStatesURL, idCountry];
// NSLog(@"url: %@", url);
State *state;
[self getObjects:state ofClass:NSClassFromString(@"State") fromUrl:url withPost:nil orPut:nil token:nil callName:@"getStates" andAlertTitle:@"States not loaded"];
}
...
我試圖在我的類中實現完成處理塊,但由於所有方法(getObjec t,createUserWithUsername ...,getStates)在同一個類中,我從不同的ViewController調用它不工作...可能我正以錯誤的方式實現它。你能給我更多的細節,或者是一個簡單的例子嗎? – nabrugir
@nabrugir:將完成塊作爲最後一個參數傳入方法 - 在方法簽名的末尾添加類似'completion:(void(^)(id data,NSError * error))completion'的東西,然後執行類似如果(完成)完成(數據,無);'在主線程上成功或'如果(完成)完成(無,錯誤);'在主線程上出錯。 – Isaac