[iOS] Observable 클래스를 이용한 데이터 바인딩

frogKing·2022년 7월 6일
0

개요

데이터가 변경될 때 마다 UI를 변경해주려면 여러가지 방법이 있다. 그중에서 Observable 클래스를 이용해서 데이터 바인딩을 구현해볼 것이다.

Observable 클래스

  • listener : value가 변경되면 실행되는 함수.
  • bind : listener에 value가 변경되면 동작할 함수를 넣어주는 함수.
  • value - didset : value가 변경될 때 listener를 실행시켜줌.
class Observable<T> {
    
    typealias Listener = (T) -> Void
    var listener: Listener?
    
    func bind(_ listener: Listener?) {
        self.listener = listener
        listener?(value)
    }
    
    var value: T {
        didSet {
            listener?(value)
        }
    }
    
    init(_ value: T) {
        self.value = value
    }
}

Observable 적용하기

  • shared : UserModelService를 싱글턴으로 사용할 수 있게 해줌.
  • userModelPath : 아직 경로를 모르기 때문에 Observable(nil)로 초기화.
  • userModelPath.value : value를 변경하자마자 위에서 설명했던 listener가 동작됨.
class UserModelService {
    
    static let shared = UserModelService()
    
    var userModelPath: Observable<URL?> = Observable(nil)
    
        func getTempUserModel(url: String) {
        let destinationPath: DownloadRequest.Destination = { _, _ in
            let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0];
            let fileURL = documentsURL.appendingPathComponent("my_mesh.obj")
            return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
        }
        
        let url = K.flaskURL + url
        AF.download(url, to: destinationPath)
            .downloadProgress { progress in
            }
            .responseData { response in
                switch response.result {
                case .success:
                    print("Success")
                    // self.userModelPath.value = self.getFilePathInDocuments(fileName: "my_mesh.obj")
                    self.userModelPath.value = response.fileURL
                case .failure(let e):
                    print(e)
                }
            }
    }

}
profile
내가 이걸 알고 있다고 말할 수 있을까

0개의 댓글