برنامه نویس وب و موبایل


جمعه 24 آبان
MVC

پیاده سازی Router با Alamofire در Swift

دوشنبه, 10 تیر 1398

من توی این قسمت می خوام Router  در Alamofire  پیاده کنم اگه با این کتابخونه آشنایی داشته باشید باید بدونید برای فراخوانی API ها استفاده میشه و کتابخونه خیلی محبوبی هست و میشه به راحتی ازش استفاده کرد اما مشکلی که هست اینه که برای فراخونی  API داخل کنترلر ها کدهای زیادی زده میشه که هم باعث هدر رفتن وقت برنامه نویس به خاطر یک کار تکراری میشه هم کنترلرهامون به شدت حجیم می کنه بهترین راه حل برا این مشکل Router  هست متاسفانه توی خود گیتهاب Alamofire  توضیحات ناقصی ارائه شده و خیلی از نیازها رو پوشش نمیده من توی خیلی از سایت های خارجی چرخیدم و تونستم یه Router  جامع پیاده کنم که تمامی نیازهامون پوشش بده از متد ها get و post و ... تا ست کردن توکن در هدر درخواست و فرستادن پارامتر و حتی کوئری استرینگ درخواست get


اول از همه ما به یک enum احتیاج داریم که همون Router   ما هست که از URLRequestConvertible ارث بری می کنه من هر بخشی کدهاش جدا می ذارم اما همشون داخل همین enum هستند در ضمن یه خطا اینجا نشون میده که بهش اهمیت ندید بعدا فیکسش می کنیم

 

import Alamofire

enum Router: URLRequestConvertible {

     static let baseURLString = ""

}

توی کد بالا فقط baseURLString با آدرس سرورتون ست کنید

در ادامه کد های زیر داخل enum می ذاریم 

    case get(apiName: String)
    case getWhithQuery(apiName: String, query:String)
    case getWhithToken(apiName: String, token:String)
    case post(apiName: String, parameters: [String: Any])
    case postWithToken(apiName: String, parameters: [String: Any], tokenValue: String)
    case put(apiName: String, parameters: [String: Any], tokenValue: String)
    case patch(apiName: String, parameters: [String: Any], tokenValue: String)
    case delete(apiName: String, tokenValue: String)

من تمام متدهایی که فکر می کردم برای یک پروژه نیازه اینطوری تعریف کردم حالا با خودتونه عشقتون کشید از اینها کمتر کنید یا بهش اضافه کنید فقط در صورت اضافه یا کم کردن بخشهای مختلفش باید تغییر بدید که پای خودتونه wink

بخش های بعدی هم زیر همین کدهای بالا بذارید تا زمانی که بهتون بگم


    // MARK: - Method
    var method: HTTPMethod {
        switch self {
        case .get, .getWhithQuery, .getWhithToken:
            return .get
        case .post, .postWithToken:
            return .post
        case .put:
            return .put
        case .patch:
            return .patch
        case .delete:
            return .delete
        }
    }

تو این بخش نوع متد هامون تعریف کردیم که get باشن یا ...    


    // MARK: - Path
    var path: String {
        switch self {
        case .get(let apiName), .getWhithQuery(let apiName, _), .getWhithToken(let apiName, _), .post(let apiName, _), .postWithToken(let apiName, _, _), .put(let apiName, _, _), .patch(let apiName, _, _), .delete(let apiName, _):
            return apiName
        }
    }
    

توی اینجا آدرس کامل API می سازیم که برای هر متد چی باشه که از ورودی متد ها به اسم apiName می گیریم


    // MARK: - Parameters
    private var parameters: [String: Any]? {
        switch self {
        case .get, .getWhithToken, .delete :
            return nil
        case .post(_, let parameters), .postWithToken(_, let parameters, _), .put(_, let parameters, _), .patch(_, let parameters, _):
            return parameters
        case .getWhithQuery(_, let query):
            return (["filter": query])
        }
    }

تو این بخش برای متد هایی که پارامتر دارن پارامتر ست می کنیم برای اونهایی که پارامتری ندارن nil و برای کوئری استرینگ هم جدا


    // MARK: - token
    private var token: String?{
        switch self {
        case .get, .getWhithQuery, .post:
            return nil
        case .getWhithToken(_, let tokenValue ), .postWithToken(_, _, let tokenValue ), .put(_, _, let tokenValue ), .patch(_, _, let tokenValue ), .delete(_, let tokenValue):
            return (tokenValue)
        }
    }

تو این بخش برای متد هایی که نیاز هست token ست می کنیم که این مقدار هم از ورودی متد می گیریم


    func asURLRequest() throws -> URLRequest {
        let url = try Router.baseURLString.asURL()
        
        var urlRequest = URLRequest(url: url.appendingPathComponent(path))
        urlRequest.httpMethod = method.rawValue
        if let t = token {
            urlRequest.setValue(t, forHTTPHeaderField: "access_token")
        }
        let encoding: ParameterEncoding = {
            switch method {
            case .get:
                return URLEncoding.default
            default:
                return JSONEncoding.default
            }
        }()
        return try encoding.encode(urlRequest, with: parameters)
    }

حالا رسیدیم به بخش اصلی با گذاشتن کدهای بالا اون خطایی که اولش گفتم رفع میشه توی اینجا براساس اینکه پارامتر داره یا نه توکن داره یا نه یه درخواست می سازه که همون چیزی هست که ما می خوایم


خوب بخش Router تموم شد حالا یه کلاس می سازیم با کد های زیر

class ApiHelper : NSObject {
    static let sharedInstants = ApiHelper()
    
    func getMainData(_ completionHandler: @escaping(Any, Bool) -> Void) {
        Alamofire.request(Router.get(apiName: "/api/v1/Categories/getAppMainData")).responseJSON { response in
            switch response.result {
            case .success(_):
                if let Json = response.result.value as? NSDictionary {
                    if let hasError = Json["hasError"] as? Bool {
                        if hasError {
                            if let error = Json["error"] as? NSDictionary {
                                completionHandler(error, hasError)
                            }
                        } else {
                            if let data = Json["response"] {
                                completionHandler(data, hasError)
                            }
                        }
                    }
                }
            case .failure(_):
                completionHandler(response.error.debugDescription,true)
            }
        }
    }

}

به ازای هر API یه متد می سازیم و بعد به جای گذاشتن آدرس API متد های Router می ذاریم و مقادیر ورودیش با توجه به نیازمون پر می کنیم و بعدش می تونیم توی کنترلرمون این متد ها رو درخواست بدیم کدهای کاملش توی github خودم گذاشتم اگه قسمتیش متوجه نشدید یه نگاه بندازید مشکلتون حل میشه امیدوارم خوشتون اومده باشه heart

 



نظرات

Drag to order
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
نظر تایید شده ای برای این مطلب وجود ندارد .