通用 API 请求处理程序

Common API request handler

我的应用程序中的一个请求如下所示:

-(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];
    }
}

这只是服务调用之一。有数百个。目前我正在控制器本身中编写这些内容(我知道这种方法不好 :))。
我正在寻找一种方法,我可以在一个 class 中编写所有基于请求的代码并在任何地方访问它。
有那么一刻,我想到了创建 Singleton。但是我不确定是否为此创建 Singleton。
也想过创建一个协议,但最后我不得不在控制器中实现它。
我可以采用哪些不同的模式,以便我对到处重复的代码有一个共同的 class。

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

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

您可以尝试使用 AFNetworking 进程调用 API 。在这里,我们可以将调用写在一个 viewController 中,并可以导入 VC ,您可以在需要时随时调用任何 API 。

我这样做过,我做了一个实用程序class

这是我的 webservice.h 文件

#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

这里我创建了两个处理程序,一个用于完成,另一个用于失败

这是 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;
}

然后在任何需要调用网络服务的地方,只要传递 urlparameters[=19= 即可调用 post 和 gte 方法]

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

    } faliureHandler:^(NSError *error) {

    }];

在Swift中:

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;
    }
}