Upgrade to Pro — share decks privately, control downloads, hide ads and more …

プロジェクト内のURLを Associated Valuesで 管理してみる

プロジェクト内のURLを Associated Valuesで 管理してみる

Taiki Suzuki

August 23, 2016
Tweet

More Decks by Taiki Suzuki

Other Decks in Programming

Transcript

  1. จࣈྻʹΑΔURLͷ؅ཧ let urlString = "https://qiita.com/api/v2/items" let queryString = "?page=1&per_page=20&query=swift+user%3Amarty-suzuki" guard

    let url = NSURL(string: urlString + queryString) else { return } let session = NSURLSession.sharedSession() let task = session.dataTaskWithURL(url) { data, response, error in //ड͚औͬͨσʔλͷॲཧ } task.resume()
  2. Associated ValuesʹΑΔURLͷ؅ཧ let query: [GetPath.SearchQuery] = [.Word("swift"), .User("marty-suzuki")] let path:

    GetPath = .Items(page: 1, perPage: 100, query: query) guard let url = NSURL(path: path) else { return } let session = NSURLSession.sharedSession() let task = session.dataTaskWithURL(url) { data, response, error in //ड͚औͬͨσʔλͷॲཧ } task.resume()
  3. GetPath Enum 1 enum GetPath { enum SearchQuery { case

    User(String) case Word(String) func toString() -> String { switch self { case .User(let name): return ("user:" + name).RFC3986Encode case .Word(let word): return word.RFC3986Encode } } } case Items(page: Int, perPage: Int, query: [SearchQuery]) //... var pathString: String { switch self { case .Items: return "/items" } } }
  4. GetPath Enum 2 extension GetPath { var queryString: String {

    switch self { case .Items(let page, let perPage, let query): let searchQueries: [String] = query.flatMap { $0.toString() } let searchQueryString = searchQueries.reduce("") { $0 == "" ? $1 : $0 + "+" + $1 } let parameters = [ URLQueryParameter(name: "page", value: page), URLQueryParameter(name: "per_page", value: perPage), URLQueryParameter(name: "query", value: searchQueryString, needsEncode: false) ] return convertParametersToString(parameters) } } private func convertParametersToString(queries: [URLQueryParameter?]) -> String { let queries: [String] = queries.flatMap { $0?.toPrameterString } let queryString: String = queries.reduce("") { $0 == "" ? $1 : $0 + "&" + $1 } return queryString } }
  5. URLQueryParameter struct URLQueryParameter { let name: String let value: String

    var toPrameterString: String { return "\(name)=\(value)" } //... init?(name: String, value: Any?, needsEncode: Bool = true) { guard let value = value, let encodedValue = URLQueryParameter.encodedValue(value, needsEncode: needsEncode) else { return nil } self.value = encodedValue self.name = name } }
  6. NSURL extension NSURL { private static let baseUrlString = "https://qiita.com/api/v2"

    convenience init?(path: GetPath) { self.init(string: NSURL.baseUrlString + path.pathString + "?" + path.queryString) } }
  7. ड͚औͬͨσʔλͷॲཧ let task = session.dataTaskWithURL(url) { data, response, error in

    if let error = error { print(error) return } guard let data = data else { return } do { let anyObject = try NSJSONSerialization.JSONObjectWithData($0.1, options: .AllowFragments) guard let array = as? [[String : NSObject]] else { return } let models: [Item] = array.flatMap({ Item(dictionary: $0) }) print(Int(response.allHeaderFields["Total-Count"] as? String ?? "")) models.forEach { print($0.title) } } catch let e as NSError { print(e) } }
  8. QiitaApiClient https://github.com/marty-suzuki/QiitaApiClient let query: [QiitaGetPath.SearchQuery] = [.Word("swift"), .User("marty-suzuki")] let method:

    QiitaHttpMethod = .Get(.Items(page: 1, perPage: 100, query: query)) QiitaApiClient.sharedClient.request(method) { (response: QiitaResponse<[QiitaItem]>) in switch response.result { case .Success(let models): print(response.totalCount) models.forEach { print($0.title) } case .Failure(let error): print(error) } }