{"id":2996,"date":"2017-05-04T18:03:44","date_gmt":"2017-05-04T09:03:44","guid":{"rendered":"http:\/\/redwing.moo.jp\/cocoa\/?p=2996"},"modified":"2017-05-04T18:03:44","modified_gmt":"2017-05-04T09:03:44","slug":"swift3-apikit-objectmapper-snapkit-%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6-web-api-%e3%81%ab%e3%82%a2%e3%82%af%e3%82%bb%e3%82%b9%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f%e4%bb%b6","status":"publish","type":"post","link":"https:\/\/redwing.moo.jp\/cocoa\/archives\/2996","title":{"rendered":"Swift3, APIKit, ObjectMapper, SnapKit \u3092\u4f7f\u3063\u3066 Web API \u306b\u30a2\u30af\u30bb\u30b9\u3057\u3066\u307f\u305f\u4ef6"},"content":{"rendered":"<p>\u6700\u8fd1\u306f\uff0cSwift3 \u3067 iOS \u30a2\u30d7\u30ea\u3092\u958b\u767a\u3057\u3066\u3044\u308b\u306e\u3067\u3059\u304c\uff0c\u6539\u3081\u3066\u4f7f\u7528\u3057\u3066\u3044\u308b\u30e9\u30a4\u30d6\u30e9\u30ea\u306b\u3064\u3044\u3066\u8abf\u3079\u3066\u307f\u305f\uff0e<br \/>\n\u4ed5\u4e8b\u3067\u306f\u65e5\u3005\u5b9f\u88c5\u3057\u306a\u304f\u3066\u306f\u3044\u3051\u306a\u3044\u30c6\u30fc\u30de\u304c\u3042\u308a\uff0c\u306a\u304b\u306a\u304b\u5168\u4f53\u3092\u4fef\u77b0\u3059\u308b\u6a5f\u4f1a\u304c\u306a\u3044\u306e\u3067\uff0cGW \u3092\u671f\u306b\u78ba\u8a8d\u3057\u3066\u307f\u305f\u3068\u3044\u3046\u3068\u3053\u308d\u3067\u3059\uff0e<br \/>\n\u30cd\u30c3\u30c8\u4e0a\u3067\u516c\u958b\u3055\u308c\u3066\u3044\u308b\u30e9\u30a4\u30d6\u30e9\u30ea\u306b\u95a2\u3059\u308b\u8a18\u4e8b\u3092\u3056\u3063\u3068\u30c1\u30a7\u30c3\u30af\u3057\u307e\u3057\u305f\u304c\uff0c\u516c\u958b\u304b\u30891\u5e74\u4ee5\u4e0a\u7d4c\u3063\u3066\u3044\u308b\u3053\u3068\u3082\u3042\u308a\uff0c\u306a\u304b\u306a\u304b\u305d\u306e\u307e\u307e\u306e\u30b3\u30fc\u30c9\u3067\u52d5\u4f5c\u3055\u305b\u308b\u3053\u3068\u304c\u96e3\u3057\u3044\u3088\u3046\u3060\u3063\u305f\u306e\u3067\uff0c\u500b\u4eba\u7684\u306a\u30e1\u30e2\u3068\u3057\u3066\u7c21\u5358\u306a\u30b3\u30fc\u30c9\u3092\u66f8\u304f\u3053\u3068\u306b\u3057\u307e\u3057\u305f\uff0e<\/p>\n<p>\u3067\u306f\u65e9\u901f\uff0c\u30b5\u30f3\u30d7\u30eb\u3067\u4f7f\u7528\u3059\u308b Web API \u3092\u9078\u3073\u307e\u3059\uff0e<\/p>\n<h4>1. Web API \u3092\u9078\u3076<\/h4>\n<p>\u25bc \u304a\u5929\u6c17Web\u30b5\u30fc\u30d3\u30b9\u4ed5\u69d8<br \/>\n<a href=\"http:\/\/weather.livedoor.com\/weather_hacks\/webservice\" target=\"_blank\">http:\/\/weather.livedoor.com\/weather_hacks\/webservice<\/a><br \/>\n\u30e9\u30a4\u30d6\u30c9\u30a2\u3067\u7121\u6599\u63d0\u4f9b\u3057\u3066\u3044\u308b Web API \u306e\u3088\u3046\u3067\u3059\uff0e<br \/>\n\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u300c\u5730\u57dfID\u300d\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3067\u5929\u6c17\u60c5\u5831\u3092\u53d6\u5f97\u3067\u304d\u308b\u3088\u3046\u3067\u3059\uff0e<\/p>\n<p>\uff08\u4f8b\uff09\u300c\u798f\u5ca1\u770c\u30fb\u4e45\u7559\u7c73\u306e\u5929\u6c17\u300d\u3092\u53d6\u5f97\u3059\u308b\u5834\u5408\u306f\uff0c\u4ee5\u4e0b\u306eURL\u306b\u30a2\u30af\u30bb\u30b9\u3057\u3066JSON\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u3067\u304d\u308b\u3068\u306e\u3053\u3068\uff0e<br \/>\n<a href=\"http:\/\/weather.livedoor.com\/forecast\/webservice\/json\/v1?city=400040\" target=\"_blank\">http:\/\/weather.livedoor.com\/forecast\/webservice\/json\/v1?city=400040<\/a><\/p>\n<p>\u7c21\u5358\u305d\u3046\u306a\u306e\u3067\uff0c\u3053\u308c\u306b\u3057\u307e\u3059\uff0e<\/p>\n<h4>2. APIKit \u3067\u30ea\u30af\u30a8\u30b9\u30c8<\/h4>\n<p>Xcode 8.3.2 \u3067 Swift3 \u3092\u4f7f\u7528\u3057\uff0c\u30b7\u30f3\u30b0\u30eb\u30da\u30fc\u30b8\u30a2\u30d7\u30ea\u3092\u4f5c\u6210\u3057\u307e\u3059\uff0e<br \/>\nCocoaPods \u3067\uff0cAPIKit \/ ObjectMapper \/ SnapKit \u3092\u5c0e\u5165\u3057\u307e\u3059\uff0e<\/p>\n<pre>\r\n<strong>APIKit<\/strong>\r\n<a href=\"https:\/\/github.com\/ishkawa\/APIKit\" target=\"_blank\">https:\/\/github.com\/ishkawa\/APIKit<\/a>\r\n- iOS 8.0 \u4ee5\u964d\u306b\u5bfe\u5fdc\uff0e\r\n\r\n<strong>ObjectMapper<\/strong>\r\n<a href=\"https:\/\/github.com\/Hearst-DD\/ObjectMapper\" target=\"_blank\">https:\/\/github.com\/Hearst-DD\/ObjectMapper<\/a>\r\n\r\n<strong>SnapKit<\/strong>\r\n<a href=\"http:\/\/cocoadocs.org\/docsets\/SnapKit\/0.10.0\/index.html\" target=\"_blank\">http:\/\/cocoadocs.org\/docsets\/SnapKit\/0.10.0\/index.html<\/a>\r\n<a href=\"https:\/\/github.com\/SnapKit\/SnapKit\" target=\"_blank\">https:\/\/github.com\/SnapKit\/SnapKit<\/a>\r\n<\/pre>\n<p>Xcode \u3067\u4f5c\u6210\u3055\u308c\u305f ViewController.swift \u306b Web API \u30ea\u30af\u30a8\u30b9\u30c8\u306e\u30b3\u30fc\u30c9\u3092\u8a18\u8ff0\u3057\u307e\u3059\uff0e<\/p>\n<pre lang=\"java\" line=\"1\">\r\nprivate func sendWeatherAPI() {\r\n    let request = WeatherRequest(city: 130010)\r\n    Session.send(request) { [weak self] result in\r\n        switch result {\r\n        case .success(let response):\r\n            self?.dispWetherResponse(dto: response)\t\/\/ \u30d3\u30e5\u30fc\u306b\u53d6\u5f97\u30c7\u30fc\u30bf\u3092\u8868\u793a\u3059\u308b\r\n\r\n        case .failure(let error):\r\n            print(\"error: \\(error)\")\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>API \u30ea\u30af\u30a8\u30b9\u30c8\u306f WeatherRequest \u3068\u3044\u3046\u540d\u524d\u306b\u3057\u307e\u3057\u305f\uff0e<br \/>\nhttp:\/\/weather.livedoor.com\/forecast\/webservice\/json\/v1?city=400040 \u306b\u30a2\u30af\u30bb\u3059\u308b\u3059\u308b\u306e\u3067\u3053\u3093\u306a\u611f\u3058\u3067\u3057\u3087\u3046\uff0e<\/p>\n<pre lang=\"objc\" line=\"1\">\r\nimport Foundation\r\nimport APIKit\r\nimport ObjectMapper\r\n\r\nstruct WeatherRequest: Request {\r\n    typealias Response = WeatherResponse\r\n    let city: Int\r\n    \r\n    init(city: Int) {\r\n        self.city = city\r\n    }\r\n    var baseURL: URL {\r\n        return URL(string: \"http:\/\/weather.livedoor.com\/forecast\/webservice\/json\")!\r\n    }\r\n    var method: HTTPMethod {\r\n        return .get\r\n    }\r\n    var path: String {\r\n        return \"v1\"\r\n    }\r\n    var parameters: Any? {\r\n        return nil\r\n    }\r\n    var queryParameters: [String: Any]? {\r\n        return [\"city\": city.description]\r\n    }\r\n    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {\r\n        guard let object = Mapper<Response>().map(JSONObject: object) else {\r\n            return Response()\r\n        }\r\n        return object\r\n    }\r\n}\r\n<\/pre>\n<h4>3. \u53d6\u5f97\u3057\u305f\u30c7\u30fc\u30bf\u3092\u30de\u30c3\u30d4\u30f3\u30b0<\/h4>\n<p>WebAPI \u3067\u53d6\u5f97\u3057\u305f\u30c7\u30fc\u30bf\u304c<br \/>\n<strong>func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {<\/strong><br \/>\n\u306b\u6e21\u3055\u308c\u307e\u3059\u306e\u3067\uff0cstruct \u306b\u30de\u30c3\u30d4\u30f3\u30b0\u3057\u307e\u3059\uff0e<br \/>\n\u307e\u305f\uff0c\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u3042\u304c\u308a\uff0c\u8fd4\u5374\u3059\u308b\u30c7\u30fc\u30bf\u306e\u65b9\u304c\u30aa\u30d7\u30b7\u30e7\u30ca\u30eb\u3067\u306a\u304f\u306a\u3063\u3066\u3044\u308b\u3088\u3046\u3067\u3059\uff0e<\/p>\n<p>\u3068\u308a\u3042\u3048\u305a\uff0c3\u3064\u306e\u30c7\u30fc\u30bf\u3060\u3051\u683c\u7d0d\u3059\u308b\u3053\u3068\u306b\u3057\u307e\u3059\uff0e<br \/>\n\u968e\u5c64\u304c\u4e00\u3064\u4e0b\u306e\u9805\u76ee\u306b\u3082 <strong>map[&#8220;description.text&#8221;]<\/strong> \u306e\u3088\u3046\u306b\u3067\u53c2\u7167\u3067\u304d\u308b\u306e\u304c\u4fbf\u5229\u3067\u3059\u306d\uff0e<\/p>\n<pre lang=\"objc\" line=\"1\">\r\nimport Foundation\r\nimport ObjectMapper\r\n\r\nstruct WeatherResponse: Mappable {\r\n    var publicTime = \"\"\r\n    var title = \"\"\r\n    var description = \"\"\r\n\r\n    init() {\r\n    }\r\n    init?(map: Map) {\r\n    }\r\n\r\n    mutating func mapping(map: Map) {\r\n        self.publicTime <- map[\"publicTime\"]\r\n        self.title <- map[\"title\"]\r\n        self.description <- map[\"description.text\"]\r\n    }\r\n}\r\n<\/pre>\n<p>WeatherResponse \u304c\uff0cViewController.swift \u306e Web API \u30ea\u30af\u30a8\u30b9\u30c8\u90e8\u5206\u306e\u30af\u30ed\u30fc\u30b8\u30e3\u30fc\u8a18\u8ff0\u306b\u8fd4\u3055\u308c\u308b\u306e\u3067\uff0c\u753b\u9762\u306b\u8868\u793a\u3057\u3066\u304a\u3057\u307e\u3044\u3067\u3059\uff0e<\/p>\n<h4>4. SnapKit \u3067\u5236\u7d04\u3092\u6307\u5b9a\u3059\u308b<\/h4>\n<p>\u3042\u3068\uff0cSnapKit \u3067\u8868\u793a\u7528\u30e9\u30d9\u30eb\u4f4d\u7f6e\u3092\u8abf\u6574\u3057\u3066\u307f\u307e\u3059\uff0e<br \/>\n<strong>SnapKit \u3067\u5236\u7d04\u3092\u6307\u5b9a\u3059\u308b\u308f\u3051\u3067\u3059\u304c\uff0c\u6307\u5b9a\u524d\u306b\u30d3\u30e5\u30fc\u306b\u5bfe\u3057\u3066\u30e9\u30d9\u30eb\u3092 addSubview() \u3057\u3066\u304a\u304b\u306a\u304f\u3066\u306f\u306a\u308a\u307e\u305b\u3093\uff0e<\/strong><\/p>\n<p>\u5236\u7d04\u306e\u6307\u5b9a\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u3057\u307e\u3057\u305f\uff0e<br \/>\n\u4e00\u5ea6\uff0cAutolayout \u306e\u5236\u7d04\u6761\u4ef6\u3092 Xcode \u304b\u3089\u884c\u3044\u307e\u3057\u305f\u304c\uff0c\u5927\u5909\u3060\u3063\u305f\u8a18\u61b6\u304c\u3042\u308a\uff0c\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u3060\u3051\u3067\u5236\u7d04\u3092\u6307\u5b9a\u3067\u304d\u308b\u306e\u306f\u5927\u5909\u4fbf\u5229\u304b\u3068\u601d\u3044\u307e\u3059\uff0e<\/p>\n<pre lang=\"objc\" line=\"1\">\r\ntitleLabel.snp.makeConstraints { make in\r\n    make.top.equalTo(20)\r\n    make.left.right.equalTo(view).inset(10)\r\n    make.height.equalTo(30)\r\n}\r\npublicTimeLabel.snp.makeConstraints { make in\r\n    make.top.equalTo(titleLabel.snp.bottom)\r\n    make.left.right.equalTo(view).inset(10)\r\n    make.height.equalTo(30)\r\n}\r\n<\/pre>\n<p>titleLabel \u306e\u4e0b\u306b publicTimeLabel \u304c\u914d\u7f6e\u3055\u308c\u308b\u3088\u3046\u306b\u5236\u7d04\u3092\u6307\u5b9a\u3057\u3066\u3044\u307e\u3059\uff0e<br \/>\n\u307e\u305f\uff0c\u305d\u308c\u305e\u308c\u306e\u9ad8\u3055\u306f 30 \u3067\u3059\uff0e<\/p>\n<p>\u7c21\u5358\u306b\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3063\u305f\u691c\u8a3c\u3067\u3057\u305f\uff0e<\/p>\n<h4>\u25bc \u8ffd\u8a18<\/h4>\n<p>Himotoki \u3063\u3066\u3044\u3046\u30e9\u30a4\u30d6\u30e9\u30ea\u3082\u7d50\u69cb\u7d39\u4ecb\u3055\u308c\u3066\u3044\u308b\u306a\u3041\u30fc\u30fc<br \/>\n<a href=\"https:\/\/github.com\/ikesyo\/Himotoki\" target=\"_blank\">https:\/\/github.com\/ikesyo\/Himotoki<\/a><\/p>\n<a href=\"https:\/\/twitter.com\/redwing1300?ref_src=twsrc%5Etfw\" class=\"twitter-follow-button\" data-size=\"large\" data-show-count=\"false\">Follow @redwing1300<\/a><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content --><div id=\"redwi-3167962166\" class=\"redwi- redwi-entity-placement\"><script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-9652476346722993\" crossorigin=\"anonymous\"><\/script><ins class=\"adsbygoogle\" style=\"display:block;\" data-ad-client=\"ca-pub-9652476346722993\" \ndata-ad-slot=\"\" \ndata-ad-format=\"auto\"><\/ins>\n<script> \n(adsbygoogle = window.adsbygoogle || []).push({}); \n<\/script>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>\u6700\u8fd1\u306f\uff0cSwift3 \u3067 iOS \u30a2\u30d7\u30ea\u3092\u958b\u767a\u3057\u3066\u3044\u308b\u306e\u3067\u3059\u304c\uff0c\u6539\u3081\u3066\u4f7f\u7528\u3057\u3066\u3044\u308b\u30e9\u30a4\u30d6\u30e9\u30ea\u306b\u3064\u3044\u3066\u8abf\u3079\u3066\u307f\u305f\uff0e \u4ed5\u4e8b\u3067\u306f\u65e5\u3005\u5b9f\u88c5\u3057\u306a\u304f\u3066\u306f\u3044\u3051\u306a\u3044\u30c6\u30fc\u30de\u304c\u3042\u308a\uff0c\u306a\u304b\u306a\u304b\u5168\u4f53\u3092\u4fef\u77b0\u3059\u308b\u6a5f\u4f1a\u304c\u306a\u3044\u306e\u3067\uff0cGW \u3092\u671f\u306b\u78ba\u8a8d\u3057\u3066 &hellip; <a href=\"https:\/\/redwing.moo.jp\/cocoa\/archives\/2996\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"meta-nav\">&rarr;<\/span><\/a><!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46,116],"tags":[168,169,170],"class_list":["post-2996","post","type-post","status-publish","format-standard","hentry","category-ios","category-swift","tag-apikit","tag-objectmapper","tag-snapkit"],"_links":{"self":[{"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/posts\/2996","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/comments?post=2996"}],"version-history":[{"count":7,"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/posts\/2996\/revisions"}],"predecessor-version":[{"id":3003,"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/posts\/2996\/revisions\/3003"}],"wp:attachment":[{"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/media?parent=2996"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/categories?post=2996"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redwing.moo.jp\/cocoa\/wp-json\/wp\/v2\/tags?post=2996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}