#はじめに
こんにちは、RxSwiftを軽く勉強したので
アウトプットしてみようということで記事を書いております。
#なんで勉強しようと思ったの
RxSwift書けたらかっこよさそうって思っただけです!
#お願い
まずRxSwiftってなんぞやって人は、今の世の中最高に便利なので
インターネットを使って調べるところからお願いします。
わからない語句などがありましたら調べながら読んでいただけると幸いです。
##準備をしましょう
xcodeを開いてプロジェクトを作りましょう。
今回ライブラリを管理にCocoaPodsを使うのでターミナルを開いて対象のディレクトリに移動して
pod init
をしたらPodfileが生成されるので好きな方法でPodfileを開いて、
今回使うライブラリは
- RxSwift
- Alamofire
- Alamofire-SwiftyJSON
の3つなので
target 'playRxSwift' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'RxSwift'
pod 'Alamofire'
pod 'Alamofire-SwiftyJSON'
# Pods for playRxSwift
end
以上のようにPodfileに追加します
そしたらターミナルでpod install
とコマンドを打ったらライブラリのインストールが始まります。
##実際にコードを書いていきましょう
まず最初に生成されるViewControllerに
import UIKit
import RxSwift
import Alamofire
import Alamofire_SwiftyJSON
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
使いたいライブラリを宣言します
もしno such module RxSwift
のようなエラーがでたらcmd + bをすれば治ると思います。
次にAPI通信をしてGitHubにある自分のリポジトリを取得する処理を書いていきます。
class ApiRequest {
private let baseUrl: String = "https://api.github.com/users/shuuun/repos"
func getResponse() -> Observable<DataResponse<JSON>> {
return Observable.create { observer in
Alamofire.request(self.baseUrl)
.responseSwiftyJSON { response in
print("JSONあげるわ")
observer.onNext(response)
observer.onCompleted()
}
return Disposables.create()
}
}
}
Alamofireを使ってAPI通信を行う処理を行い、返り値にDataResponse型のJSONを返すObservableを作ります。
Observable.createというのはColdなObservableを作ります。
(Coldというのはsubscribe(購読)されないと動かないObservableです。)
クロージャの引数はObserverType型が渡していて、(コードではobserverという名前で書いてます)
その中にはイベントを通知するメソッドが入っています。
次にAlamofire.request()でapi通信を行います。
クロージャの引数はDataResponse型(コードではresponseという名前で書いています。)
responseがきたらobserverの中にあるonNextメソッドを使ってresponseの中身を渡してイベントを通知します。
onComplete()は完了を通知するものです。
これで一旦API通信の処理はおしまいです。
次にViewControllerに戻って処理を書いていきます
import UIKit
import RxSwift
import Alamofire
import SwiftyJSON
class ViewController: UIViewController {
private let apiRequest = ApiRequest()
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
start()
}
private func getResult() -> Observable<DataResponse<JSON>> {
return self.apiRequest.getMethod()
}
private func start() {
print("始まり")
getResult()
.subscribe(
onNext: { res in
if let json: JSON = res.value {
self.jsonParse(Json: json)
}
},
onCompleted: {
print("終わり")
}
).disposed(by: disposeBag)
}
private func jsonParse(Json: JSON) {
let json = JSON(Json)
json.forEach{ (_, json) in
print(json["name"])
print(json["url"])
}
}
}
private func getResult() -> Observable<DataResponse<JSON>> {
return self.apiRequest.getResponse()
}
getResultメソッドでは、getResponseメソッドを使ってDataResponse型を受け取り、returnしています。
private func start() {
print("始まり")
getResult()
.subscribe(
onNext: { res in
if let json: JSON = res.value {
self.jsonParse(Json: json)
}
},
onCompleted: {
print("終わり")
}
).disposed(by: disposeBag)
}
startメソッドでは、getResult()をsubscribeすることでgetResult()が動いてapi通信が行われます。
private let disposeBag = DisposeBag()
.disposed(by: disposeBag)
これを使うことで購読する必要がなくなったものを解除することができます。
getResponse()にonNext()があることにより、イベントが発行されクロージャの引数にDataResponse型の値が入ってきます。
if letを使うことにより、オプショナル型の変数をアンラップしたjsonを使うことができます。
private func jsonParse(Json: JSON) {
let json = JSON(Json)
json.forEach{ (_, json) in
print(json["name"])
print(json["url"])
}
}
そのjsonをjsonParseメソッドで引数として受け取り、SwiftyJSONを使って使いたいものだけ取り出しています。
これでコードは以上です。startメソッドをviewDidLoadにて呼び出してみましょう
始まり
JSONあげるわ
calculatorApp
https://api.github.com/repos/shuuun/calculatorApp
kaiwa
https://api.github.com/repos/shuuun/kaiwa
LikesTinderSNS
https://api.github.com/repos/shuuun/LikesTinderSNS
MEANtemplate
https://api.github.com/repos/shuuun/MEANtemplate
padthon
https://api.github.com/repos/shuuun/padthon
pixiv-hack
https://api.github.com/repos/shuuun/pixiv-hack
quizApp
https://api.github.com/repos/shuuun/quizApp
終わり
結果はこんな感じです。
リポジトリ名とurlが表示されましたね
お疲れ様でした。
##おまけ
今回はロード時にstartメソッドを呼び出していましたが、
例えばボタンを押したらstartメソッドを使いたい場合もあると思います。
Rxを使わなかったらActionでボタンを押したらメソッドを呼び出せばいいですが、
Rx使って書く場合にはRxCocoaというライブラリを使うと簡単に書くことができます。
(RxCocoaというのはUIKitの様々なクラスで使用できるプロパティーをextensionとして定義してくれているものです)
PodfileにRxCocoaを書いてpod install
しましょう。
適当にアウトレットなどでbuttonを紐付けて
button.rx.tap
.subscribe( onNext:{[weak self] in
self?.start()
}).disposed(by: disposeBag)
viewDidLoadにこれを追記します。
そうするとボタンのタップを購読して押されたらonNextでイベント発行してstartメソッドを呼び出すことができます。
##終わりに
読んでいただきありがとうございました!!
間違ったこと書いていたら教えていただけると嬉しいです!
アプリを作ってストア公開してみたいのでRxSwift使ってのんびり開発して行こうと思います