Slide 1

Slide 1 text

ϓϩδΣΫτ಺ͷURLΛ Associated ValuesͰ ؅ཧͯ͠ΈΔ marty-suzuki

Slide 2

Slide 2 text

ࣗݾ঺հ Github: https://github.com/marty- suzuki Twitter: https://twitter.com/ marty_suzuki

Slide 3

Slide 3 text

SAHistoryNavigationVie wController https://github.com/marty-suzuki/ SAHistoryNavigationViewController 1264 stars

Slide 4

Slide 4 text

URLEmbeddedView https://github.com/marty-suzuki/ URLEmbeddedView 280 stars

Slide 5

Slide 5 text

http://qiita.com/api/v2/docs

Slide 6

Slide 6 text

URL https://qiita.com/api/v2/items? page=1&per_page=20&query=swift+user%3Amarty-suzuki

Slide 7

Slide 7 text

จࣈྻʹΑΔ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()

Slide 8

Slide 8 text

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()

Slide 9

Slide 9 text

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" } } }

Slide 10

Slide 10 text

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 } }

Slide 11

Slide 11 text

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 } }

Slide 12

Slide 12 text

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) } }

Slide 13

Slide 13 text

ड͚औͬͨσʔλͷॲཧ 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) } }

Slide 14

Slide 14 text

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) } }

Slide 15

Slide 15 text

͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ marty-suzuki