How should I create model class to call API (Using

2020-07-26 14:09发布

问题:

Currently I am calling an API in viewcontroller itself but this is not good programming practice as per MVC.
Here is my code:

-(void)fetchData{

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:@"https://dl.dropboxusercontent.com/s/2iodh4vg0eortkl/facts.json"]];
    [request setHTTPMethod:@"GET"];
    [request addValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
    [request addValue:@"text/plain" forHTTPHeaderField:@"Accept"];

    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
        NSData * responseData = [requestReply dataUsingEncoding:NSUTF8StringEncoding];
        if (responseData != nil) {

            NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
            NSLog(@"requestReply: %@", jsonDict);
            self.content = jsonDict[@"rows"];
            self.navigationTitle = jsonDict[@"title"];


            dispatch_async(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];

            });

            NSLog(@"result %@", self.content);

        }

    }] resume];


}

Can you please suggest how should I arrange code/file to follow MVC pattern?
If I create separate model class how should I manage existing code and how I transfer response to viewcontroller?

回答1:

Swift 3 Try this:

class WebRequester: NSObject {

    static let shared = WebRequester()

    func request(vc:UIViewController, url: String, parameter:String?, callback:@escaping (_ result:NSDictionary?, _ error:NSError?) -> Void) {

        let requestURL = url

        print("..............................")
        print("URL: ",requestURL)
        print("Parameter: ",parameter ?? "nil")
        print("..............................")

        var request = URLRequest(url: URL(string:requestURL)!)
        request.httpMethod = "POST"

        if parameter != nil {
            request.httpBody = parameter!.data(using: .utf8)
        }


        let session = URLSession.shared
        let task = session.dataTask(with: request, completionHandler: {data, response, error in
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
            DispatchQueue.main.async {
                if error == nil {
                    do {
                        let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
                        print(json)
                        let dic = json as? NSDictionary
                        if dic != nil {
                            callback(json as? NSDictionary, nil)
                        }
                        else {
                            vc.alert(title: "Oops..", message: "Something went wrong please try again later")
                        }
                    }
                    catch {
                        print(error.localizedDescription)
                        callback(nil,error as NSError?)
                    }
                }
                else {
                    print(error?.localizedDescription ?? "")
                    callback(nil, error as NSError?)
                }
            }
        })
        task.resume()
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
    }
}

ObjectiveC

WebRequester.h

#import <Foundation/Foundation.h>

@interface WebRequester : NSObject

+(id)shared;

-(void)request1:(NSString *)url parameter:(NSString *)params callback:(void(^)(NSDictionary *result, NSError *error))callback;

@end

WebRequester.m

#import "WebRequester.h"

@implementation WebRequester

+(id)shared {
    static WebRequesterObjC *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

-(void)request1:(NSString *)url parameter:(NSString *)params callback:(void(^)(NSDictionary *result, NSError *error))callback {

    NSString *requestUrl = url;

    NSLog(@"====================");
    NSLog(@"%@",requestUrl);
    NSLog(@"%@",params);
    NSLog(@"====================");

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:requestUrl]];
    request.HTTPMethod = @"POST";

    if (params != nil) {
        request.HTTPBody = [params dataUsingEncoding:NSUTF8StringEncoding];
    }

    NSURLSession* session = [[NSURLSession alloc] init];
    NSURLSessionDataTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            if (data != nil) {
                NSError * err;
                NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
                if (err == nil) {
                    callback(dic,nil);
                }
                else {
                    callback(nil,err);
                }
            }
        }
        else {
            callback(nil,error);
        }
    }];
    [task resume];
}

@end

call as follow

  [WebRequesterObjC.shared request1:<#url#> parameter:params callback:^(NSDictionary *result, NSError *error) {
        if (error == nil) {
            NSLog(@"%@",result)
        }
  }];


回答2:

class RestAPI: NSObject {
    static let sharedInstance = RestAPI()

    func restAPIMtd(urlString: String,  methodName: String, params: String = "", CompletionHandler:@escaping (_ success: Bool, _ response: NSDictionary)  -> Void) {
        // create post request
        let url = URL(string: urlString)!
        var request = URLRequest(url: url)
        request.httpMethod = methodName
        let postData = params.data(using: .utf8)
        request.httpBody = postData
        // insert json data to the request
        request.timeoutInterval = 60
        let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
            guard error == nil else {
                self.showErrorMessage(error:(error)!)
                CompletionHandler(false, [:])
                return
            }
            guard let data = data else {
                self.showErrorMessage(error:(error)!)
                CompletionHandler(false, [:])
                return
            }
            do {
                if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: AnyObject] {
                    CompletionHandler(true, json as NSDictionary)
                    return
                }
            } catch let error {
                CompletionHandler(false, [:])
                self.showErrorMessage(error: error)
            }
        })
        task.resume()
    }

    func showErrorMessage(error:Error) -> Void {
        DispatchQueue.main.async {
            print(error.localizedDescription)
        }
    }
}