通用API请求处理程序

时间:2016-07-04 12:37:48

标签: ios objective-c iphone xcode nsurlconnection

我的应用中的一个请求如下:

-(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 还考虑了创建协议,但最后我必须在控制器中实现它 我可以采用哪些不同的模式,以便我有一个我在各处重复的代码的公共类。

3 个答案:

答案 0 :(得分:1)

我这样做了,我做了一个实用类

这是我的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;

这是我使用的帖子方法

-(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

来调用post和gte方法,无论您需要哪个方法
[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;
    }
}

答案 1 :(得分:0)

  1. 创建WebService,它将处理所有请求的逻辑。
  2. 提取在每个请求中重复的代码。
  3. 将与UIService相关的代码从WebService移至UIViewController类。
  4. 基本上UIViewController对请求创建一无所知,只调用WebService然后处理结果。

答案 2 :(得分:0)

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