2017-01-11 11 views
0

FIRUser와 FIRDatabaseReference를 취하는 fusing 이니셜 라이저로 클래스를 생성하려고합니다. Firebase 데이터베이스에서 데이터를 다운로드하고 반환되는 것을 기반으로 자체 변수를 설정합니다. 그렇지 않으면 이니셜 라이저가 실패합니다.Firebase Data Pull에서 클래스 초기화하기

데이터가 클로저에 다운로드되지만 다운로드가 발생하지 않은 것처럼 모든 것이 기본값으로 되돌아갑니다.

나는이 서버 로직을 클래스 초기화 자 안에 포함하고 정말로 싶습니다. 어떤 식 으로든 이걸 안전하게 할 수 있을까요? 나는 많은 것을 시도해 왔고 그것을 이해할 수 없다.

init?(from user: FIRUser, withUserReference ref: FIRDatabaseReference){ 
    let userID = user.uid 

    var init_succeeded = false 

    //These values don't matter. If the init fails 
    //It'll return an empty class. 
    //Yes this is a hack lol 

    self.incognito = false 
    self.email = "NO" 
    self.username = "NOPE" 
    self.ref = ref 
    self.fir_user = user 
    self.mute_all = false 

    //Getting the information from the database 
    ref.child(userID).observeSingleEvent(of: .value, with: { (snapshot) in 
     // Get user value 
     let value = snapshot.value as? NSDictionary 
     //Unpacking user preferences 
     self.incognito = (value?["incognito"] as? Bool)! 
     self.mute_all = (value?["mute_all"] as? Bool)! 
     self.email = (value?["email"] as? String)! 
     self.username = (value?["username"] as? String)! 
     init_succeeded = true 
    }) { (error) in 
     print("ERROR : \(error.localizedDescription)") 
    } 

    if !init_succeeded { return nil } 
} 

고마워요! - 키넌

답변

0

간단한 답 : 없음

당신 간단하게해야이 비동기 진술에 의존의 함수에서하지 return 값. init_succeededtrue으로 설정되고이 반환되기 때문에이 메서드는 항상 nil을 반환합니다. Firebase 쿼리는 비동기식이기 때문에 observeSingleEvent을 호출하면 해당 명령문이 실행 완료 될 때까지 기다리지 않고 비동기 적으로 실행하고 나머지 코드 (이 경우에는 return)와 함께 계속 실행합니다.

완료 폐쇄는 당신이 얻을 수있는 가장 가까운 (하지만 코드가 정확히 초기화 방법에 포함되지 않습니다) :

init(from user: FIRUser, withUserReference ref: FIRDatabaseReference, completion: @escaping (Bool) -> Void){ 
let userID = user.uid 

// default values 
self.incognito = false 
self.email = "NO" 
self.username = "NOPE" 
self.ref = ref 
self.fir_user = user 
self.mute_all = false 

//Getting the information from the database 
ref.child(userID).observeSingleEvent(of: .value, with: { (snapshot) in 
    // Get user value 
    let value = snapshot.value as? NSDictionary 
    //Unpacking user preferences 
    self.incognito = (value?["incognito"] as? Bool)! 
    self.mute_all = (value?["mute_all"] as? Bool)! 
    self.email = (value?["email"] as? String)! 
    self.username = (value?["username"] as? String)! 

    completion(true)  // true = success 
}) { (error) in 
    completion(false) // false = failed 
    print("ERROR : \(error.localizedDescription)") 
} 

} 

그리고 지금 기본적으로이

let myObject = myClass(from: someUser, withUserReference: someRef, completion: { success in 
if success { 
    // initialization succeeded 
} 
else { 
    // initialization failed 
} 
}) 
처럼 사용

일반적으로 이니셜 라이저에서 데이터를 검색하지 말 것을 제안합니다. 데이터를 검색 할 수있는 다른 함수를 작성하고 기본값을 설정하십시오. init()

+0

도움을 주셔서 감사합니다! 마지막으로 스냅 샷을 클래스 이니셜 라이저에 전달하고 나머지는 처리하도록했습니다. 다시 한 번 감사드립니다! –

관련 문제