2016-07-04 156 views
0

一個在我的應用程序的要求是這樣的:通用API請求處理

-(void)login 
{ 
    @try { 
     NSString *str = [NSString stringWithFormat:TGURL_LOGIN]; 
     NSURL *url = [NSURL URLWithString:str]; 
     [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 
     NSDictionary *requestData = @{@"---": ----, 
             @"---": ----, 
             @"OutResponse": [NSNumber numberWithInteger:0]}; 

     NSError *error; 
     NSData *postData = [NSJSONSerialization dataWithJSONObject: requestData options:0 error:&error]; 

     NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]]; 


     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
     [request setURL:url]; 
     [request setHTTPMethod:@"POST"]; 
     [request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
     [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
     [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
     [request setHTTPBody:postData]; 

     NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
     __block int iSuccess = 0; 

     [NSURLConnection 
     sendAsynchronousRequest:request 
     queue:queue 
     completionHandler:^(NSURLResponse *response, 
          NSData *data, 
          NSError *error) { 
      [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; 
      if ([data length] >0 && error == nil){ 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        iSuccess = [self parseResponse:data]; 
       }); 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        if(iSuccess == 1) 
        { 
         [[NSUserDefaults standardUserDefaults] setObject:_email.text forKey:@"EmailText"]; 
         [[NSUserDefaults standardUserDefaults] setObject:_password.text forKey:@"PasswordText"]; 
         [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"User_Logged_In"]; 
         [[NSUserDefaults standardUserDefaults]synchronize]; 

         [TGProjectHandler saveCookiesToDefaults]; 
         [self getUserID]; 
        } 
        else if(iSuccess == 3) 
        { 
         [[NSUserDefaults standardUserDefaults] setObject:_email.text forKey:@"EmailText"]; 
         [[NSUserDefaults standardUserDefaults] setObject:_password.text forKey:@"PasswordText"]; 
         [[NSUserDefaults standardUserDefaults]synchronize]; 
         [self.view endEditing:YES]; 
         [TGProjectHandler saveCookiesToDefaults]; 
         [TGProjectHandler removeLoadingIndicator]; 
         [self performSegueWithIdentifier:@"ShowJoinGroup" sender:nil]; 
        } 
        else 
        { 
         [[[UIAlertView alloc] initWithTitle: NSLocalizedString(@"Login_failed", nil) 
                message:NSLocalizedString(@"Invalid_credentials", nil) 
                delegate:nil 
              cancelButtonTitle:@"OK" 
              otherButtonTitles:nil] show]; 
         [TGProjectHandler removeLoadingIndicator]; 
         self.view.userInteractionEnabled = YES; 
        } 
       }); 
      } 
      else if ([data length] == 0 && error == nil){ 
       NSLog(@"Empty Response, not sure why?"); 
      } 
      else if (error != nil){ 
       NSLog(@"%@", error.description); 
       self.view.userInteractionEnabled = YES; 
       [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Login_failed", nil) 
              message:error.localizedDescription 
              delegate:nil 
            cancelButtonTitle:@"OK" 
            otherButtonTitles:nil] show]; 
       [TGProjectHandler removeLoadingIndicator]; 
       self.view.userInteractionEnabled = YES; 
      } 
     }]; 
    } 
    @catch (NSException *exception) { 
     [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; 
    } 
} 

這僅僅是一個服務調用的一個。有幾百個人。目前我正在寫這些控制器本身(壞方法,我知道:))。
我正在尋找一種方法,我可以在一個類中編寫所有基於請求的代碼,並隨處訪問它。
我想了一下創建Singleton。但我不確定爲此創建Singleton。
還想過創建一個協議,但最後我不得不在控制器中實現它。
我可以使用哪些不同的模式,以便我可以在任何地方重複使用代碼。

+1

你可以嘗試創建一個NSObject類,在那裏你可以聲明websersevice post和get方法。您只需將webservice名稱和參數傳遞給該webservice類,並在需要該數據的類中獲取其響應。您可以爲web服務響應創建一個完成處理程序。 –

+0

@RahulPatel:如何處理完成處理程序? – Nitish

回答

1

我曾經做過這樣的,我做了一個實用工具類

這是

#import <Foundation/Foundation.h> 

typedef void (^webCompletionHandler)(NSData *data); 
typedef void (^webFailuerHandler)(NSError *error); 


@interface WebService : NSObject 



-(BOOL)callPostWebService:(NSString *)methodURL 
        param:(NSMutableDictionary *)params 
     completionHandler:(webCompletionHandler)completion 
      failuerHandler:(webFailuerHandler)failuer; 


-(BOOL)callgetWebService:(NSString *)methodURL 
     completionHandler:(webCompletionHandler)completion 
      failuerHandler:(webFailuerHandler)failuer; 



@end 

在這裏,我創建了我webservice.h文件中的兩個處理器一個完成,另一個用於故障

這些是PostGet的兩種方法

-(void)getWebServiceCall:(NSString *)methodURL 
       parameters:(NSMutableDictionary *)parameters 
     completionHandler:(webCompletionHandler)completion 
      faliureHandler:(webFailureHandler)failure; 

-(void)postWebserviceCall:(NSString *)methodURL 
        param:(NSMutableDictionary *)params 
     completionHandler:(webCompletionHandler)completion 
      faliureHandler:(webFailureHandler)failure; 

這是POST方法我已經使用

-(void)callPostWebService:(NSString *)methodURL 
        param:(NSMutableDictionary *)params 
     completionHandler:(webCompletionHandler)completion 
      failuerHandler:(webFailuerHandler)failuer{ 

    if(![Utility isReachable]){ 
     DisplayLocalizedAlert(@"Network is not reachable"); 
     return; 
    } 


    NSLog(@"%@",methodURL); 
    NSURLRequest *request = [self createRequest:params url:methodURL]; 

    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURLSessionDataTask *dataTask = 
    [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 


     dispatch_async(dispatch_get_main_queue(), ^{ 
      if(error != nil){ 
       failuer(error); 
       return ; 
      } 
      else{ 

       NSError* error; 
       NSDictionary* json = [NSJSONSerialization 
             JSONObjectWithData:data 
             options:kNilOptions 
             error:&error]; 
       NSLog(@"json %@",json); 

       completion(data); 
      } 
     }); 
    }]; 
    [dataTask resume]; 

    return true; 
} 

然後在任何你需要調用web服務,你只需調用後與GTE方法,無論你需要通過傳遞urlparameters

[webService postWebserviceCall:strURL param:dicInfo completionHandler:^(id data) { 

    } faliureHandler:^(NSError *error) { 

    }]; 

在斯威夫特:

import UIKit 
import MobileCoreServices 
import CoreLocation 


typealias webCompletionHandler = (data : NSData) -> Void; 
typealias webFailuerHandler = (error : NSError,isCustomError : Bool) -> Void; 


let failureStatusCode = 0; 
let successStatusCode = 200; 

class WebServiceCall :NSObject { 

    static var webService = WebServiceCall(); 

    override init() { 

    } 

func callPostWebService(methodURL methodURL :String, param:NSDictionary, completionHandler:webCompletionHandler, failureHandler: webFailuerHandler) -> Bool 
    { 
     if (isInternetHasConnectivity() == false) { 
      let myError = NSError(domain: "Internet is not available", code: 1001, userInfo: nil) 
      failureHandler(error: myError, isCustomError: true); 
//   AlertView.showMessageAlert(myError.domain) 
      return false; 
     } 

     let request = self.createRequest(param, strURL: methodURL) 

     let serviceTask = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { 
      data, response, error in 

      dispatch_async(dispatch_get_main_queue(), {() -> Void in 

       if(error != nil){ 

        failureHandler(error: error!, isCustomError: false); 
       } 
       else{ 

        let response = Utilities.parseData(data!) 
        let status = response.objectForKey("status") as! Int; 

        if(status == successStatusCode){ 
         completionHandler(data: data!) 
        } 
        else { 
         let msg = response.objectForKey("message") as! String 
         let error = NSError(domain: msg, code: Int(status), userInfo: nil); 
         failureHandler(error: error, isCustomError: true); 
        } 

       } 

      }) 
     }) 
     serviceTask.resume(); 

     return true; 
    } 
} 
+0

如何以及在哪裏定義了webCompletionHandler和webFailureHandler? – Nitish

+0

謝謝。讓我在接受之前嘗試這個:) – Nitish

+0

我發現在swift中轉換此代碼時遇到了一些困難。你有這個快捷版嗎?否則我會爲此創建客觀的課程。 – Nitish

0
  1. 創建WebService,它將處理所有請求的邏輯。
  2. 提取在每個請求中重複的代碼。
  3. 將Web相關代碼從WebService移動到UIViewController類。

基本上UIViewController對於創建請求一無所知,它只是調用WebService,然後處理結果。

0

您可以嘗試使用AFNetworking過程來調用API。在這裏,我們可以在一個viewController中編寫調用,並且可以導入該VC,您可以隨時調用任何API。