Created
April 24, 2017 09:43
-
-
Save syou007/bdfb06fe117c36b909eb84ffa1a8a723 to your computer and use it in GitHub Desktop.
SwiftでAPIリクエストを発行する。 ref: http://qiita.com/syou007/items/566a62ee5eaa96f5a2d3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import Alamofire | |
import RxSwift | |
import ObjectMapper | |
import AlamofireObjectMapper | |
// Routerを実装してAPIを作成ます。 | |
public protocol Router { | |
// URLを返却 | |
func url() -> String | |
// メソッドを返却 | |
func method() -> Alamofire.HTTPMethod | |
// 実際のデータ取得処理 | |
func request<T: Mappable>() -> Observable<[T]> | |
func request<T: Mappable>() -> Observable<T> | |
func request<T: Mappable>(parameters: Parameters?) -> Observable<[T]> | |
func request<T: Mappable>(parameters: Parameters?) -> Observable<T> | |
// エラー時の処理 | |
func errorHandle(error: Error, statusCode: Int?) | |
} | |
// Routerの共通処理をあらかじめ定義しておく。 | |
extension Router { | |
// Defaultはget処理 | |
func method() -> Alamofire.HTTPMethod { return .get } | |
// 実際のリクエスト発行 | |
func request<T: Mappable>() -> Observable<[T]> { | |
return self.request(parameters: nil) | |
} | |
func request<T: Mappable>(parameters: Parameters? = nil) -> Observable<[T]> { | |
return Observable.create { (observable: AnyObserver<[T]>) in | |
// リクエストを投げる。 | |
API.createRequest(router: self, parameters: parameters).responseArray { (response: DataResponse<[T]>) in | |
switch response.result { | |
case .success(let value): | |
observable.on(.next(value)) | |
observable.onCompleted() | |
case .failure(let error): | |
self.errorHandle(error: error, statusCode: response.response?.statusCode) | |
} | |
} | |
return Disposables.create() | |
} | |
} | |
func request<T: Mappable>() -> Observable<T> { | |
return self.request(parameters: nil) | |
} | |
func request<T: Mappable>(parameters: Parameters? = nil) -> Observable<T> { | |
return Observable.create { (observable: AnyObserver<T>) in | |
// リクエストを投げる。 | |
API.createRequest(router: self, parameters: parameters).responseObject { (response: DataResponse<T>) in | |
switch response.result { | |
case .success(let value): | |
observable.on(.next(value)) | |
observable.onCompleted() | |
case .failure(let error): | |
observable.onError(error) | |
self.errorHandle(error: error, statusCode: response.response?.statusCode) | |
} | |
} | |
return Disposables.create() | |
} | |
} | |
// エラー処理 | |
func errorHandle(error: Error, statusCode: Int?) { | |
if statusCode == 401 { | |
// 共通エラー処理をここに記載します。 | |
} | |
} | |
} | |
// API処理 | |
class API { | |
// ホスト名 | |
private static let Host = "http://localhost:3000/api/v1" | |
// 共通ヘッダー | |
static let CommonHeaders:HTTPHeaders = [ | |
"Authorization": "Test", | |
"Version": Bundle.main.infoDictionary!["CFBundleShortVersionString"]! as! String, | |
"Accept": "application/json" | |
] | |
// リクエスト処理の生成 | |
fileprivate class func createRequest(router:Router, parameters: Parameters? = nil) -> Alamofire.DataRequest { | |
return Alamofire.request("\(Host)\(router.url())", | |
method:router.method(), | |
parameters: parameters, | |
encoding: JSONEncoding.default, | |
headers: API.CommonHeaders).validate() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github "ReactiveX/RxSwift" | |
github "Alamofire/Alamofire" ~> 4.4 | |
github "Hearst-DD/ObjectMapper" ~> 2.2 | |
github "tristanhimmelman/AlamofireObjectMapper" ~> 4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"id": 1, | |
"name": "hoge" | |
}, | |
{ | |
"id": 2, | |
"name": "foo" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
API.Users.get(1).request().subscribe(onNext: { (user:Company) in | |
DebugLog("id = \(user.id)") | |
}).addDisposableTo(disposeBag) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"users": [ | |
{ | |
"id": 1, | |
"name": "hoge" | |
}, | |
{ | |
"id": 2, | |
"name": "foo" | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
API.createRequest(router: self, parameters: parameters) | |
.responseArray { (keyPath: "users", response: DataResponse<[T]>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
return Observable.create { (observable: AnyObserver<T>) in | |
... | |
return Disposables.create() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import ObjectMapper | |
class User: Mappable { | |
var id = 0 | |
var name = "" | |
required init?(map: Map) {} | |
// Mappable | |
func mapping(map: Map) { | |
id <- map["id"] | |
name <- map["name"] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension API { | |
enum Users: Router { | |
// データ一覧取得 | |
case list | |
// データ一件取得 | |
case get(Int) | |
// ルーティングはここで行います。 | |
func url() -> String { | |
switch self { | |
case .list: | |
return "/users" | |
case .get(let id): | |
return "/users/\(id)" | |
} | |
} | |
// methodも上記同様に定義できます。未定義の場合はgetが使われます。 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UsersViewController: UIViewController { | |
// APIの解放で使います。わからない人はこのまま実装すればOKです。 | |
let disposeBag = DisposeBag() | |
override func viewDidAppear(_ animated: Bool) { | |
super.viewDidAppear(animated) | |
// 一覧取得 | |
// パラメータをつけたい場合はparametersに[String:String]で定義。なくても動きます。 | |
API.Users.list.request(parameters: nil).subscribe(onNext: { (users:[User]) in | |
for user in users { | |
DebugLog("id = \(user.id)") | |
} | |
}).addDisposableTo(disposeBag) | |
// 一件のデータ取得 | |
API.Users.get(1).request().subscribe(onNext: { (user:User) in | |
DebugLog("id = \(user.id)") | |
}).addDisposableTo(disposeBag) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment