Я сделал 30 секунд видео проблемы, которую я описываю ниже:
У меня есть UserService
класс, который является частью SceneDelegate, и внедрил его в мой первый отображаемый LoginView
:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var userService = UserService()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = LoginView().environmentObject(userService)
...
В LoginView у меня есть навигационная ссылка, которую я запускаю через asyn c callback программно:
NavigationLink(destination: WelcomeView(), isActive: $showWelcomeView) { EmptyView() }
Когда я получаю пользователя от userService
, я показываю WelcomeView
struct WelcomeView: View {
@EnvironmentObject var userService: UserService
var body: some View {
VStack {
CircleImage(image: userService.user.image!)
.offset(y: -220)
.frame(height: 140)
.frame(width: 140)
...
как вы видите, мой userService является @EnvironmentObject
.
В первый раз, когда я показываю WelcomeView
по ссылке навигации, все работает хорошо, но когда я возвращаюсь к LoginView
и снова захожу в пу sh WelcomeView
я вижу эту ошибку:
Fatal error: Unexpectedly found nil while unwrapping an Optional value:
По какой-то причине мой userService.user.image
стал nil
после того, как я вернитесь к предыдущему представлению входа в систему и снова посмотрите pu sh Welcome.
Затем я попытался отладить его и обнаружил, что каким-то образом мой асин c обратный вызов здесь игнорируется. Вы можете видеть, что я делаю два асин c звонка. Я добавил комментарий ниже, где я никогда не получаю обратный вызов для второго запуска:
func getUser(with email: String, completion: @escaping (UserFetchResult) -> Void) {
let findUsers:PFQuery = PFUser.query()!
findUsers.whereKey("email", equalTo: email)
findUsers.findObjectsInBackground { (objects, error) in
if error == nil {
guard let firstFoundUser = objects?.first as? PFUser else {
print("Get users error")
completion(.failure)
return
}
self.user = User(pfUser: firstFoundUser)
// IGNORED THIS CALL AND DISPLAY WelcomeView without waiting completion handler.
self.user.avatar?.getDataInBackground(block: { (data, error) in
if error == nil {
if let unwrappedData = data {
if let unwrappedUIImage = UIImage(data: unwrappedData) {
self.user.image = Image(uiImage: unwrappedUIImage)
}
}
}
if self.user.image == nil {
self.user.image = Image("ManPlaceholderAvatar")
}
completion(.success(data: self.user))
})
} else {
print("Get users error")
completion(.failure)
}
}
}
Вы можете проверить подробности отладки в этом видео * 1039. *.