Not sure how to append array outside of async call
62 观看
1回复
444 作者的声誉
I'm trying to get certain child nodes named City from Firebase using observeSingleEvent
but I am having issues trying to pull it into the main thread. I have used a combination of completion handlers and dispatch calls but I am not sure what I am doing wrong, in addition to not being that great in async stuff. In viewDidLoad
I'm trying to append my keys from the setupSavedLocations
function and return it back to savedLocations
I feel like I am close. What am I missing?
Edit: Clarity on question
import UIKit
import Firebase
class SavedLocationsViewController: UIViewController {
var userID: String?
var savedLocations: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
setupSavedLocations() { (savedData) in
DispatchQueue.main.async(execute: {
self.savedLocations = savedData
print("inside", self.savedLocations)
})
}
print("outside",savedLocations)
}
func setupSavedLocations(completion: @escaping ([String]) -> ()) {
guard let user = userID else { return }
let databaseRef = Database.database().reference(fromURL: "https://************/City")
var dataTest : [String] = []
databaseRef.observeSingleEvent(of: .value, with: {(snapshot) in
let childString = "Users/" + user + "/City"
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
dataTest.append(key)
}
completion(dataTest)
})
}
sample output
outside []
inside ["New York City", "San Francisco"]
作者: LampPost
的来源
发布者: 2017 年 12 月 27 日
回应 1
1像
1042 作者的声誉
The call to setupSavedLocations
is asynchronous and takes longer to run than it does for the cpu to finish viewDidLoad
that is why your data is not being shown. You can also notice from your output that outside
is called before inside
demonstrating that. The proper way to handle this scenario is to show the user that they need to wait for an IO call to be made and then show them the relevant information when you have it like below.
class SavedLocationsViewController: UIViewController {
var myActivityIndicator: UIActivityIndicatorView?
override func viewDidLoad() {
super.viewDidLoad()
setupSavedLocations() { (savedData) in
DispatchQueue.main.async(execute: {
showSavedLocations(locations: savedData)
})
}
// We don't have any data here yet from the IO call
// so we show the user an indicator that the call is
// being made and they have to wait
let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
myActivityIndicator.center = view.center
myActivityIndicator.startAnimating()
self.view.addSubview(myActivityIndicator)
self.myActivityIndicator = myActivityIndicator
}
func showSavedLocations(locations: [String]) {
// This function has now been called and the data is passed in.
// Indicate to the user that the loading has finished by
// removing the activity indicator
myActivityIndicator?.stopAnimating()
myActivityIndicator?.removeFromSuperview()
// Now that we have the data you can do whatever you want with it here
print("Show updated locations: \(locations)")
}
作者: Nordeast
发布者: 2017 年 12 月 27 日
来自类别的问题 :
- ios iPhone app in landscape mode, 2008 systems
- ios 如何为我的网站提供iPhone的图标?
- ios 如何调整UITextView的内容大小?
- ios iPhone viewWillAppear没有开火
- ios 如何在顶部状态栏中显示加载指示器
- ios How to save picture to iPhone photo library?
- ios 如何禁用UITableView选择?
- ios 以编程方式在iOS中获取自己的电话号码
- ios 如何更改iOS应用的名称?
- ios -didSelectRowAtIndexPath:未被调用
- swift 如何以编程方式确定我的应用程序是否在iphone模拟器中运行?
- swift iOS:将UTC NSDate转换为本地时区
- swift 如何在运行时为UIBarButtonItem设置目标和操作
- swift 单个UILabel中的粗体和非粗体文字?
- swift 找到三次贝塞尔曲线上的点的切线
- swift 如何计算两个日期之间的差异?
- swift 如何从UILabel的第n行获取text / String?
- swift 我可以以编程方式滚动到UIPickerView中的所需行吗?
- swift 在UIScrollView中关闭键盘
- swift 如何控制UILabel中的行间距