Search
🔫

[FireBase - iOS] 시작하기 전에... (네트워크 요청 구현 원칙)

부제
카테고리
네트워킹
세부 카테고리
FireBase
Combine 카테고리
최종편집일
2022/07/16 15:17
작성중
관련된 포스팅
생성 일시
2022/07/16 15:14
태그
안녕하세요 iOS 개발자 루크입니다.
이 섹션에서는
Firebase 를 활용해 API 통신을 이해하고 활용해보도록하겠습니다
Firebase 의 여러가지 API 메서드를 알아보기전에 몇가지 알아두면 좋을 원칙을 정리해보았습니다.

1 : API 메서드는 따로 struct 화 해서 사용한다.

struct AuthService { // 싱글톤 패턴 사용 static let shared = AuthService() func logUserIn(withEmail email: String, password: String, completion: @escaping (AuthDataResult?, Error?) -> Void) { //로그인 메서드 } func registerUser(credentials: AuthCredentials, completion: @escaping (Error?, DatabaseReference) -> Void) { // 회원가입 메서드 } }
Swift
복사
위 예제 코드 처럼 특정 서비스와 관련된 메서드들을 하나의 struct 또는 class 로 묶어서 관리하는 것이 좋습니다.
그 중에서도 Authentication 같은 경우 싱글톤 패턴이 적합합니다 ( 앱의 어디서든 로그인, 로그아웃, 회원가입이 가능하게 하도록 함)

2 : 건네줄 파라미터가 많은 경우 struct 로 타입을 생성해 하나의 파라미터로 건네준다.

struct AuthCredentials { let email: String let password: String let fullName: String let userName: String let profileImage: UIImage } func registerUser(credentials: AuthCredentials, completion: @escaping (Error?, DatabaseReference) -> Void) { // 회원가입 메서드 }
Swift
복사
함수에 필요한 파라미터가 많아지면 코드의 가독성이 저하됩니다.
그룹의 의미를 가지는 타입을 선언해 파라미터로 건네주면 함수의 역할이 분명해집니다.

3 : escaping 클로져를 활용해 네트워킹 결과를 UI 에 반영

func registerUser(credentials: AuthCredentials, completion: @escaping (Error?, DatabaseReference) -> Void) { let email = credentials.email let password = credentials.password let fullName = credentials.fullName let userName = credentials.userName let profileImage = credentials.profileImage guard let imageData = profileImage.jpegData(compressionQuality: 0.3) else { return } let filename = NSUUID().uuidString let storageRef = STORAGE.PROFILE_IMAGES.child(filename) storageRef.putData(imageData, metadata: nil) { meta, error in storageRef.downloadURL { url, error in guard let profileImageUrl = url?.absoluteString else { return } Auth.auth().createUser(withEmail: email, password: password) { (result, error) in if let error = error { print("DEBUG: Error is \(error.localizedDescription) ") return } else { guard let uid = result?.user.uid else { return } let values = ["email" : email, "username": userName, "fullname": fullName, "profileImageUrl" : profileImageUrl] //url 을 따로 따서 적어 놓을 것. DB.REF_UESERS.child(uid).updateChildValues(values, withCompletionBlock: completion) } } } } }
Swift
복사
위 예제 코드 처럼 네트워킹의 결과를 UI 에 반응하게 하게끔 escaping 클로져를 활용해 completion 핸들러로 비동기적인 네트워킹 요청에 대한 결과를 UI 에 적절하게 반응하게 해줍니다.
단 이경우와 같이 여러개의 네트워킹 메서드가 중첩되게 되면 분기점이 많아지고 클로져가 중첩되기 때문에 유지보수가 힘들어지므로
이는 RxSwift , Swift 의 await - async 구문 등을 사용해 해결해 보려합니다. ( 해당 부분에 대해서는 추후 포스팅과 함께 코드 리팩토링 예정)

4 : 자주 접근하게되는 URL 또는 Reference 의 경우 타입 프로퍼티로 정의해 사용합니다.

class DB { static let URL = "https://twitterclone-3af3c-default-rtdb.asia-southeast1.firebasedatabase.app" static let REF = Database.database(url: DB.URL).reference() static let REF_UESERS = DB.REF.child("users") } class STORAGE { static let REF = Storage.storage(url: "gs://twitterclone-3af3c.appspot.com/").reference() static let PROFILE_IMAGES = STORAGE.REF.child("profile_images") }
Swift
복사