2016-03-03 72 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) 
    } 
}