通用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。
还想过创建一个协议,但最后我不得不在控制器中实现它。
我可以使用哪些不同的模式,以便我可以在任何地方重复使用代码。
答
我曾经做过这样的,我做了一个实用工具类
这是
#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文件中的两个处理器一个完成,另一个用于故障
这些是Post
和Get
的两种方法
-(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方法,无论你需要通过传递url
和parameters
[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;
}
}
答
- 创建WebService,它将处理所有请求的逻辑。
- 提取在每个请求中重复的代码。
- 将Web相关代码从WebService移动到
UIViewController
类。
基本上UIViewController
对于创建请求一无所知,它只是调用WebService,然后处理结果。
答
您可以尝试使用AFNetworking过程来调用API。在这里,我们可以在一个viewController中编写调用,并且可以导入该VC,您可以随时调用任何API。
你可以尝试创建一个NSObject类,在那里你可以声明websersevice post和get方法。您只需将webservice名称和参数传递给该webservice类,并在需要该数据的类中获取其响应。您可以为web服务响应创建一个完成处理程序。 –
@RahulPatel:如何处理完成处理程序? – Nitish