티스토리 뷰
현업에선 RxSwift를 사용하고 있다.
그중 가장 많이 보이는건 .rx 이 친구.. 도대체 뭘까?
Button.rx
TextField.rx 이런건 봤는데
따로 커스텀해서 만들어져있는걸 보고 공부해야겠다 안되겠다..하고 미루고 미루던게 드디어 오늘이다.
한번 파보자 !!
.rx
Observable 타입을 표현하는 확장자로, 비동기적으로 데이터를 생성하고나 다른 이벤트를 전달 하는 시퀀스 인데 기본형태로는 아래와 같이 쓰입니다.
extension Reactive where Base: SomeType { }
가장 끝 SomeType 쪽에 (UIButton, UITextField, URLSession 등) 감지하고 싶은 특정 reactive extension을 구현합니다.
예시)
self.someButton
.rx
.tap
.bind {
print("tapped!")
}
.disposed(by: self.disposeBag)
위 코드는 someButton의 이벤트를 감지하고 있다가 눌리게 되면 "tapped" 를 프린트하는 로직 입니다.
아래는 Reactive의 내부 코드를 가져와 봤어요.
👇👇👇 Reactive.Swift 코드 👇👇👇
public struct Reactive<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
public subscript<Property>(dynamicMember keyPath: ReferenceWritableKeyPath<Base, Property>) -> Binder<Property> where Base: AnyObject {
Binder(self.base) { base, value in
base[keyPath: keyPath] = value
}
}
}
public protocol ReactiveCompatible {
associatedtype ReactiveBase
static var rx: Reactive<ReactiveBase>.Type { get set }
var rx: Reactive<ReactiveBase> { get set }
}
extension ReactiveCompatible {
public static var rx: Reactive<Self>.Type {
get { Reactive<Self>.self }
set { }
}
public var rx: Reactive<Self> {
get { Reactive(self) }
set { }
}
}
import Foundation
extension NSObject: ReactiveCompatible { }
여기서 주목할건 ReactiveCompatible 이라는 프로토콜 입니다.
이 프로토콜을 채택한 class에서는 .rx라는 프로퍼티를 쓸 수 있게 됩니다.
아래는 Reactive Extension을 사용해 만든 URLSession 입니다.
URLSession 예시 )
1. API 호출
2. Data타입의 응답값 받음
3. Data타입 디코딩
// URLSessionEx
import Foundation
import RxSwift
public enum RxURLSessionError: Error {
case unknown
case invalidResponse(response: URLResponse)
case requestFailed(response: HTTPURLResponse, data: Data?)
case deserializationFailed
}
extension Reactive where Base: URLSession {
// response
func response(request: URLRequest) -> Observable<(HTTPURLResponse, Data)> {
return Observable.create { observer in
let task = self.base.dataTask(with: request) { data, response, error in
guard let response = response,
let data = data else {
observer.onError(error ?? RxURLSessionError.unknown)
return
}
guard let httpResponse = response as? HTTPURLResponse else {
observer.onError(RxURLSessionError.invalidResponse(response: response))
return
}
observer.onNext((httpResponse, data))
observer.onCompleted()
}
task.resume()
return Disposables.create { task.cancel() }
}
}
// data
func data(request: URLRequest) -> Observable<Data> {
if let url = request.url?.absoluteString,
let data = internalCache[url] {
return Observable.just(data)
}
return response(request: request).cache().map { response, data -> Data in
guard 200..<300 ~= response.statusCode else {
throw RxURLSessionError.requestFailed(response: response, data: data)
}
return data
}
}
// decodable
func decodable<D: Decodable>(request: URLRequest,
type: D.Type) -> Observable<D> {
return data(request: request).map { data in
let decoder = JSONDecoder()
return try decoder.decode(type, from: data)
}
}
}
Usage
let urlSession = URLSession.shared
let url = URL(string: "https://peppo.tistory.com/")!
var request = URLRequest(url: url)
urlSession
.rx
.decodable(request: request, type: SomeResponse.self)
.disposed(by: disposeBag)
TestFiled 예시 )
1. textField에 text가 입력되면 해당 이벤트를 받아 print 해줌.
textField.rx.text
.subscribe(onNext: { text in
print(text ?? "")
})
.disposed(by: disposeBag)
여러가지 예시를 들면서 공부해보니까 조금은 트이는것 같다.
특히 네트워크 통신같은 경우는 현업에서도 구현되어 있어서 로직파악이 어려웠는데
이번에 공부로 많은 도움이 된거 같다.
참고
'iOS' 카테고리의 다른 글
[iOS] FileManager - 폴더, 파일 생성 & 삭제 (0) | 2023.04.04 |
---|---|
[iOS] AVAssetWriter로 비디오 저장 (2) | 2023.03.26 |
[Combine] Chapter16 : Error Handling (0) | 2023.03.01 |
[iOS] Camera 설정 - AVCaptureSession(feat. 카메라 권한 설정) (0) | 2023.02.26 |
[Combine] Chapter13 : Resource Management (0) | 2023.01.19 |
- Total
- Today
- Yesterday
- Swift joined()
- Swift 프로그래머스
- Class
- Swift 프로퍼티
- removeLast()
- Swift
- swift (programmers)
- 2023년 회고
- Swift Leetcode
- swift reduce
- Combine: Asynchronous Programming with Swift
- iOS error
- Swift ModernRIBs
- Swift RIBs
- swift protocol
- swift 고차함수
- Swift 내림차순
- swift programmers
- CS 네트워크
- 원티드 프리온보딩
- Swift init
- Swift 알고리즘
- Swift final
- RIBs tutorial
- Swift Error Handling
- Swift inout
- ios
- swift property
- RTCCameraVideoCapturer
- Swift joined
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |