2016-03-03 69 views
0

我有一個漂亮的標準問題在這裏,我有點困惑如何讓更快捷的傳統事物更優雅。Swift中的重構代碼

我在我的APIClient中有一個基本的URL字符串,一個用於不同方法的路徑,方法可能會傳入一個可選的字符串。

我該如何寫這個,使它更清潔?我覺得我寫SWIFT代碼,但不使用任何新的結構的(如門衛,讓)等

// call the API 
ApiClient.sharedInstance.getUser("56cfffce227a6c2c9b000001", successCompletion: successCompletion, failureCompletion: failureCompletion) 

// setting the current URL 
let currentURL = String("http://localhost:3000") 

// class definition 
class ApiClient { 

    var baseURL:String!; 

    // have to init the string class for the 
    init (base:String){ 
     self.baseURL = base 
    } 

    class var sharedInstance: ApiClient { 
     struct Static{ 
      static let instance = ApiClient(base: currentURL) 
     } 
     return Static.instance 
    } 


    func getUser(user_id: String?, successCompletion: ResultHandler<User>, failureCompletion:ResultHandler<FailureReason>){ 

     // this is awkward 
     var url: URLStringConvertible! 

     // this is even more awkward 
     if user_id != nil { 
      url = "\(currentURL)/users/\(user_id!).json" 
     } else { 
      url = "\(currentURL)/users/me" 
     } 

    } 
} 

回答

2

清理一些東西並刪除一些不必要的強制解開。

class ApiClient { 

var baseURL: String; 

// have to init the string class for the 
init (base:String){ 
    self.baseURL = base 
} 

class var sharedInstance: ApiClient { 
    struct Static{ 
     static let instance = ApiClient(base: currentURL) 
    } 
    return Static.instance 
} 


func getUser(user_id: String?, successCompletion: ResultHandler<User>, failureCompletion:ResultHandler<FailureReason>){ 

    var url: URLStringConvertible 
    if let user_id = user_id { 
     url = "\(currentURL)/users/\(user_id!).json" 
    } 
    else{ 
     url = "\(currentURL)/users/me" 
    } 

}

取決於你在的getUser做什麼,事情可以做不同的。

僅供參考,我傾向於對單身做到:(可以說不是最好的):

private static var realSharedInstance: Class? 
static var sharedInstance: Class { 
    get { 
     if let realSharedInstance = realSharedInstance { 
      return realSharedInstance 
     } 
     else{ 
      realSharedInstance = Class() 
      return realSharedInstance! 
      } 
    } 
} 
+0

創建單更妙的是這一個班輪:'靜態令sharedInstance = MyClass的()'HTTP:// krakendev。 io/blog/the-right-way-to-write-a-singleton –

+0

潛在的問題是你只能設置一次,所以它不是很通用。 – PeejWeej

+0

謝謝!這對單身人士有什麼好處? –

1

對於我來說,我喜歡創造一個端點爲每個端點的API支持。在這種情況下,可以通過APIClient發出請求的UsersEndpoint。 當更多端點和每個端點具有多個資源時,這更容易擴展(對我而言)。

使用代碼:

MyAPI.sharedInstance.users.getUser(id, parameters: params, success: {}, failure: {}) 
MyAPI.sharedInstance.anotherEndpoint.doSomething(parameters: params, success: {}, failure: {}) 

的類:

class MyAPI { 

    static let sharedInstance = MyAPI() 

    let users: UsersEndpoint 
    // more endpoints here 

    init() { 
    users = UsersEndpoint() 
    // .... 
    } 

} 

class APIClient { 

    static let sharedClient = APIClient() 
    var manager : Alamofire.Manager! 

    var baseURL: String 

    init() { 
    baseURL = String(format: "https://%@%@", self.instanceUrl, API.Version) 
    } 

    func get(endpoint endpoint: String, 
      parameters: [String:AnyObject], 
      success: SuccessCallback, 
      failure: FailureCallback) { 

    let requestUrl = NSURL(string: "\(self.baseURL)\(endpoint)")! 
    manager.request(.GET, requestUrl, parameters: parameters, headers: headers) 
    .validate() 
    .responseData { response in 

     switch response.result { 
     case .Success(let value): 
     if let data: NSData = value { 
      success(data: data) 
      log.verbose("Success - GET requestUrl=\(requestUrl)") 
     } 
     break; 
     case .Failure(let error): 
     failure(error: error) 
     log.error("Failure - GET requestUrl=\(requestUrl)\nError = \(error.localizedDescription)") 
     break; 
     } 

    } 
    } 

} 

class APIFacade { 

    var endpoint: String 

    init(endpoint: String) { 
    self.endpoint = endpoint; 
    } 

    func get(endpoint endpoint: String, 
      parameters: [String:AnyObject], 
      success: SuccessCallback, 
      failure: FailureCallback) { 
    APIClient.sharedClient.get(endpoint: endpoint, parameters: parameters, success: success, failure: failure) 
    } 

} 

class UsersEndpoint: APIFacade { 

    init() { 
    super.init(endpoint: "/users") 
    } 

    func getUser(id: String, parameters: [String:AnyObject], success: SuccessCallback, failure: FailureCallback) { 
    super.get(endpoint: "\(self.endpoint)/\(id)", parameters: parameters, success: success, failure: failure) 
    } 
}