2016-12-13 1 views
1

Xcode 8.1, Swift 2.3, iOS 10.1, und ich verwende FirebaseSwift - Varible verlorene Daten

ich nicht auf Daten zugreifen außerhalb Schließung bin. Ich möchte herunterladenURL1 und downloadURL2, wie self.url1 = downloadURL1

Aber downloadURL1 ist nil außerhalb Schließung.

storageRef.child(filePath1).putData(data1, metadata: metaData) { (metadata1, error1) in 
      if let error = error1 { 
       print(error.localizedDescription) 
       return 
      } else { 
       let downloadURL1 = metadata1!.downloadURL()!.absoluteString     
      } 
     } 

     storageRef.child(filePath2).putData(data2, metadata: metaData) { (metadata2, error2) in 
      if let error = error2 { 
       print(error.localizedDescription) 
       return 
      } else { 
       let downloadURL2 = metadata2!.downloadURL()!.absoluteString 
      } 
     } 
+0

Sie Variablen innerhalb des Verschlusses definieren und sie aufhören zu existieren, wenn die Abschluss endet so gut wie sie nicht außerhalb verfügbar sind ... Sie benötigen eine Klassenvariable zum Beispiel – Volker

Antwort

1

Sie sagen:

downloadURL1 ist nil außerhalb Schließung.

Ja, das macht Sinn, weil diese Schließung asynchron (d. H. Später) abläuft. Sie können es nur innerhalb des Closings verwenden (oder von einem Task, der nach Abschluss der Closure ausgeführt wird).

Zum Beispiel, wenn Sie etwas mit diesen beiden Download nur tun wollen, wenn sie beide getan, würde die Verwendung Gruppe versenden:

var downloadURL1: String? 
var downloadURL2: String? 

let group = dispatch_group_create() 

dispatch_group_enter(group) 
storageRef.child(filePath1).putData(data1, metadata: metaData) { (metadata1, error1) in 
    defer { dispatch_group_leave(group) } 

    if let error = error1 { 
     print(error.localizedDescription) 
     return 
    } else { 
     downloadURL1 = metadata1!.downloadURL()!.absoluteString     
    } 
} 

dispatch_group_enter(group) 
storageRef.child(filePath2).putData(data2, metadata: metaData) { (metadata2, error2) in 
    defer { dispatch_group_leave(group) } 

    if let error = error2 { 
     print(error.localizedDescription) 
     return 
    } else { 
     downloadURL2 = metadata2!.downloadURL()!.absoluteString 
    } 
} 

dispatch_group_notify(group, dispatch_get_main_queue()) { 
    // you use `downloadURL1` and `downloadURL2` here 
} 

// but not here 
+0

Das ist Arbeit! Ich danke dir sehr :) –

1

Wenn ich Ihr Recht bekommen, sagen Sie, dass Sie nicht downloadURL1 und downloadURL2 Werte außerhalb Ihrer Verschlüsse?

Nun, wenn das so ist, ist es völlig normal. Sie sollten Ihre Variablen lieber außerhalb des Abschlusses deklarieren. Der Versuch, die Werte dieser beiden Variablen außerhalb des Abschlusses zu verwenden, funktioniert jedoch nicht, da sie asynchron sind.

Sie möchten vielleicht auch ihre didset-Eigenschaften verwenden. Aber warum sollte man in diesem Fall downloadURL1 und downloadURL2 verwenden und nicht direkt etwas tun?

var url1: String? { 
     didSet { 
      // Do whatever you want, like call a function, once url1 is set 
     } 
    } 
    var url2: String? { 
     didSet { 
      // Do whatever you want, like call a function, once url2 is set 
     } 
    } 

    storageRef.child(filePath1).putData(data1, metadata: metaData) { (metadata1, error1) in 
     if let error = error1 { 
      print(error.localizedDescription) 
      return 
     } else if let downloadURL1 = metadata1?.downloadURL()?.absoluteString { 
      // Just to make sure it isn't nil 
      self.url1 = downloadURL1     
     } 
    } 

    storageRef.child(filePath2).putData(data2, metadata: metaData) { (metadata2, error2) in 
     if let error = error2 { 
      print(error.localizedDescription) 
      return 
     } else if let downloadURL2 = metadata2?.downloadURL()?.absoluteString { 
      self.url2 = downloadURL2    
     } 
    } 

Aber vielleicht habe ich Ihre Frage überhaupt nicht verstanden?

Edit: Ich nehme Sie verwenden das alles in einem Viewcontroller oder eine Klasse von einer Art