0

I am new to IOS. And I am using Alamofire for making network request. I have been very much successful in doing following...

  1. Making request with parameters
  2. Showing activity indicator
  3. Getting Response and hiding activity indicator
  4. Parsing response into modal

I have good concept of OOP. and I have good experience of working in android. In android I use to make a centralized class for services, and calls it from activities, and then I pass the result using callbacks.

In this way the it is more compact and avoids me in writing same code again and again. I search on it, and found that delegate are the same thing as Callbacks/Interfaces in java/android.

My Question:

Can Any one tell me how to make a Alamofire code in one class and how to call that from other View controllers with different number and type of parameters. and with different type of results to send back into related View controller? is it possible and how using swift??

Rakesh Patel
  • 1,673
  • 10
  • 27
Android teem
  • 780
  • 2
  • 13
  • 36

4 Answers4

2

Create one swift file with WebServicesCall or your preferred name and use following code. here I am using SwiftyJSON and Alamofire.

import UIKit
import Alamofire
import SwiftyJSON

struct WebService {
static func requestService(url: URL, method: HTTPMethod, parameters: Parameters, headers: HTTPHeaders? = nil, showLoaderFlag: Bool, viewController: UIViewController, completion: @escaping (_ success: JSON) -> Void) {
        /* check for internet connection */
        if(Reachability.isConnectedToNetwork()) {
            /* Show Loader here */

            print("Web Service - \(url)")
            print("Header - \(String(describing: headers))")
            print("Parameters - \(parameters)")

            /* Request configure */
            AlmofireService.Manager.request(url, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: header) .responseJSON { response in
                print("Response - \(response)")

                switch response.result {
                case .success(_):
                    /* Hide loader here */

                    let json = JSON(response.result.value!)

                    completion(json)

                case .failure(_):
                    print("Request failed with error: \(response.result.error ?? "" as! Error)")

                    if response.result.error?._code == NSURLErrorTimedOut {
                        //TODO: show response time out alert or message here
                    } else {
                        //TODO: show response failure alert or message here
                    }

                    /* Hide loader here */

                    completion(JSON.null)
                }
            }
        } else {
            print("No internet connection")

            //TODO: show no internet connection alert or message here

            let json: JSON = ["status": "nointernet",
                          "code": 503]
            completion(json)
        }
    }
    }

And then call as following when your need

func callWebService() {
        let parameters: [String: Any] = ["key": "value"] //for post request
        let headers: [String: String] = ["key": "value"]
        let url = //your url here

        WebService.requestService(url: url, method: .post, parameters: parameters, headers: headers, showLoaderFlag: true, viewController: self, completion: { response in

            guard response["code"].int != 503 else {
                print("No internet connection")
                return
            }

            guard response != .null else {
                return
            }

            /* Handle your success response here */

        })
    }
Shahrukh
  • 740
  • 7
  • 25
1

Create a NSObject class and and create a class level function inside it. and call it from any other class

import Alamofire

class Network: NSObject {

class func API_PostData(_ strURL: String, parameter Params: NSDictionary, successWithStatus1Closure: @escaping (AnyObject?) -> (), successWithStatus0Closure: @escaping (AnyObject?) -> (), failurClosure: @escaping (String?)-> ())
    {

        let Param: [String: Any] = Params.mutableCopy() as! [String : Any]


        let complite_url = BASE_URL+strURL


        if Reachability.isConnectedToNetwork(){



            Alamofire.request(complite_url, method: .post, parameters: Param ,encoding: JSONEncoding.default).responseJSON {
                response in
                if(response.result.error != nil)
                {
                    let error = response.result.error
                    if (error?.localizedDescription == "The request timed out."){
                        failurClosure("The request timed out.");
                        return
                    }
                    if (error?.localizedDescription == "Could not connect to the server."){
                        failurClosure("Could not connect to the server.");
                        return
                    }
                    if (error?.localizedDescription == "The network connection was lost."){
                        failurClosure("The network connection was lost.");
                        return
                    }
                }
                let dictResponse = response.result.value as? NSDictionary

                print("Response",response)

                if dictResponse is Dictionary<AnyHashable,Any> {
                    print("Yes, it's a Dictionary")
                }
                else{
                    print("No, it's a not a Dictionary")
                    failurClosure("Active internet connection required")
                    return
                }

                let isSuccess = dictResponse!["success"] as! Int

                if isSuccess == 1
                {
                    successWithStatus1Closure(dictResponse)
                }else{
                    successWithStatus0Closure(dictResponse)
                }

            }
        }else {

            print("Active internet connection required");
            failurClosure("Active internet connection required")
            return
        }

    }
    }

and use it like

Network.API_PostData

and xCode will autocompleted the method

Uses Example in your view controller create a method

func callApi(){
    let para = ["user_id" : USER_ID_STR,
                "page" : String(page),
                "item_per_page" : "15"
        ] as NSDictionary
    SVProgressHUD.show()
    GlobalClass.API_PostData("notifications/activities", parameter: para, successWithStatus1Closure: { (response) in

        print("response \(response)")
        SVProgressHUD.dismiss()
    }, successWithStatus0Closure:{ (response) in
        print("response \(response)")
        SVProgressHUD.dismiss()
    }, failurClosure: { (error) in
        print("error \(error ?? "ddd")")
        GlobalClass.showAlert(alertTitle: "", alertMsg: error!, view: self)
        SVProgressHUD.dismiss()
    })
}

and call it like

callApi()
Ajay saini
  • 2,352
  • 1
  • 11
  • 25
0

You can achieve your requirement by writing Callback methods or Closures. For example:

func yourMethodName(completion:@escaping (YourModelClass) -> Void,onError:@escaping (Error) -> Void) {
    let dataRequest = RequestObject()
    dataRequest.apiURL = YourApiURl
    dataRequest.headers = DesiredHeaders
    dataRequest.requestType = RequestType

    //This will be your method for the webservice call, whenever you get success or error, return a callback to the calling class via completion.
    NetworkManager.getDataFor(Request: dataRequest, success: {response in
        //print(response.responseObject!)
        let model = YourModelClass.init(WithDictionary: response.responseObject as? [String : Any])
        completion(model)
    }, failure: {error in
        onError(error)
  })
}

Hope this helps. For any query feel free to leave a comment.

iPeter
  • 1,330
  • 10
  • 26
0

Try this

Swift

In WebService Class : post the notification

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "yourNotificationName"), object: nil)

In your class where you want to receive the response : register first for the notification, and write a method to handle it. You give the corresponding selector to the method. // view did load

NotificationCenter.default.addObserver(self, selector: #selector(yourClass.handleUpdatedData), name: NSNotification.Name(rawValue: "yourNotificatioName"), object: nil)

-(void)handleUpdatedData:(NSNotification *)notification {
    NSLog(@"recieved");
    [self.tableView reloadData];
}

Objective C...

In WebService Class : post the notification

[[NSNotificationCenter defaultCenter] postNotificationName:@"DataUpdated"
                                                        object:self];

In your class where you want to receive the response : register first for the notification, and write a method to handle it. You give the corresponding selector to the method. // view did load

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleUpdatedData:)
                                             name:@"DataUpdated"
                                           object:nil];

-(void)handleUpdatedData:(NSNotification *)notification {
    NSLog(@"recieved");
    [self.tableView reloadData];
}
Prajnaranjan Das
  • 1,378
  • 1
  • 9
  • 26