通用API请求处理

问题描述:

一个在我的应用程序的要求是这样的:通用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

我曾经做过这样的,我做了一个实用工具类

这是

#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

  1. 创建WebService,它将处理所有请求的逻辑。
  2. 提取在每个请求中重复的代码。
  3. 将Web相关代码从WebService移动到UIViewController类。

基本上UIViewController对于创建请求一无所知,它只是调用WebService,然后处理结果。

您可以尝试使用AFNetworking过程来调用API。在这里,我们可以在一个viewController中编写调用,并且可以导入该VC,您可以随时调用任何API。