How should I create model class to call API (Using MVC pattern)?

Viewed 1350

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?

2 Answers
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)
        }
    }
}
Related