Невозможно исправить «Компилятор не может проверить это выражение в разумные сроки; попробуйте разбить выражение на отдельные подвыражения»

#swift #swiftui

#swift #свифтуи

Вопрос:

у меня есть три переменных, так что, похоже, возникает компилятор, когда я пытаюсь проверить, прошло ли время или нет. У меня есть

 let currentDate = Int(Date().timeIntervalSince1970)
let loginUpdateDate = sessionStore.userSession?.loginUpdateDate
let nextDateLoginUpdate = currentDate - loginUpdateDate
 

но когда я пытаюсь это сделать, я получаю

Компилятор не может проверить это выражение в разумные сроки; попробуйте разбить выражение на отдельные подвыражения

Это простая операция с Int, но кажется, что она перегружает компилятор. Я делаю это, чтобы использовать операторы if позже

 if nextDateLoginUpdate < 300
 

полный код — это:

 struct editProfileView: View {
    @State var loadImage : Image? = nil
    @State var source : UIImagePickerController.SourceType = .photoLibrary
    @EnvironmentObject var sessionStore : SessionStore
    @State var name: String = ""
    @State var bio:String = ""
    @Binding var showEditProfile:Bool
    @State var showEditPassword = false
    //    var user = User?
    @State var loadingView = false
    
    //image picker
    @State var showChoose = false
    @State var image: Image? = nil
    @State var showImagePicker = false
    @State var imageData : Data? = nil
    @State private var offsetValue: CGFloat = 0.0
    var body: some View {

            ZStack {
                VStack {
                    //переменные для даты и проверки последующего обновления данных на странице
                    //let loginUpdateDate = sessionStore.userSession?.loginUpdateDate
                    //let nextDateLoginUpdate = currentDate - loginUpdateDate
                    Group {
                        Group {
                            VStack {
                                    Group {
                                        //аватарка
                                        //если картинка не выбрана
                                        if (self.image == nil) {
                                            if (self.sessionStore.userSession?.profileImageUrl == nil) {
                                                ZStack(alignment: .bottomLeading) {
                                                    Image("user-placeholder")
                                                        .resizable()
                                                        .scaledToFill()
                                                        .clipShape(Circle())
                                                        .frame(width: 100, height: 100)
                                                    
                                                    Image(systemName: "goforward.plus").padding(5)
                                                }.frame(width: 100, height: 100)
                                                    .onTapGesture {
                                                        //выключаем если прошло меньше времени
                                                        self.showImagePicker = true
                                                }
                                            } else {
                                                if (self.loadImage == nil) {
                                                    ZStack(alignment: .bottomLeading) {
                                                        Image("user-placeholder")
                                                            .resizable()
                                                            .aspectRatio(contentMode: .fill)
                                                            .clipShape(Circle())
                                                            .frame(width: 100, height: 100)
                                                        
                                                        Image(systemName: "goforward.plus").padding(5)
                                                    }.frame(width: 100, height: 100)
                                                        .onTapGesture {
                                                            self.showChoose = true
                                                            //выключаем если прошло меньше времени
                                                    }
                                                }
                                                    
                                                else {
                                                    ZStack(alignment: .bottomLeading) {
                                                        loadImage!
                                                            .resizable()
                                                            .scaledToFill()
                                                            .clipShape(Circle())
                                                            .frame(width: 100, height: 100)
                                                        
                                                        Image(systemName: "goforward.plus").padding(5)
                                                    }.frame(width: 100, height: 100)
                                                        .onTapGesture {
                                                            self.showChoose = true
                                                            //выключаем если прошло меньше времени
                                                    }
                                                }
                                                
                                            }
                                            
                                            VStack(alignment: .center) {
                                                Text(name).font(.headline)
                                            }
                                            
                                            //если картинка выбрана
                                        } else {
                                            ZStack(alignment: .bottomLeading) {
                                                image! //может использовать "!" так как делаем проверку и уверены, что это не nil
                                                    .resizable()
                                                    .scaledToFill()
                                                    .clipShape(Circle())
                                                
                                                Image(systemName: "goforward.plus").padding(5)
                                            }.frame(width: 100, height: 100)
                                                .onTapGesture {
                                                    //                                self.showImagePicker = true
                                                    self.showChoose = true
                                            }
                                        }
                                        
                                        HStack {
                                            Text(LocalizedStringKey("Bio:")).fontWeight(.bold)
                                            Spacer()
                                        }
                                        HStack {
                                            TextField(LocalizedStringKey("Bio"), text:$bio).padding(.top)
                                        }.padding(.bottom).padding(.horizontal).background(Color("textFieldBackground")).cornerRadius(10)
                                    }
                            }
                        }.padding(.horizontal).padding(.top)
                            
                        Button(action: {
                            let currentUser = Auth.auth().currentUser
                            if (currentUser != nil) {
                                self.loadingView = true
                                let id = currentUser!.uid
//                                добавить в коллекцию ниже параметры когда получитсвя везде обновлять инфо
//                                "username" : self.name, "keywords" : self.name.splitStringToArray()
                                Ref.FIRESTORE_COLLECTION_USERS.document(id).updateData(["bio" : self.bio]) { (err) in
                                    //Конструкция: если err (ошибка) не nil, значит ест ьошибка и что-то пошло не так
                                    // если nil, значит все хорошо
                                    if let err = err {
                                        //делаем что-то если ошибка
                                        //например показываем надпись с сообщением об ошибке
                                        print("Error updating document: (err)")
                                        self.loadingView = false
                                    } else {
                                        self.sessionStore.userSession?.bio = self.bio
                                        //то же самое только если все получилось
                                        print("Document successfully updated")
                                        if (self.imageData == nil) {
                                            self.loadingView = false
                                            self.showEditProfile = false
                                        }
                                    }
                                }
                                
                                //save image
                                //Если новая картинка выбрана
                                if (self.imageData != nil amp;amp; self.sessionStore.userSession != nil) {
                                    //Сначала загружаем в хранилище, а затем ссылку на это фото обновляем в базе данных у пользователя
                                    let storageAvatarUserId = Ref.STORAGE_AVATAR_USERID(userId: Auth.auth().currentUser!.uid)
                                    let metadata = StorageMetadata()
                                    metadata.contentType = "image/jpg"
                                    //для био было
                                    //cлушатель для обновления био
                                    self.sessionStore.userSession?.bio = self.bio
                                    //для логина - апдейт
                                    self.sessionStore.userSession?.username = self.name
                                    
                                    NotificationCenter.default.post(name: NSNotification.Name("update_profile_bio"), object: nil)
                                    StorageService.updateAvatar(userId: self.sessionStore.userSession!.uid, username: self.sessionStore.userSession!.username, email: self.sessionStore.userSession!.email, imageData: self.imageData!, metaData: metadata, storageAvatarRef: storageAvatarUserId, onSuccses: {url in
                                        if url != nil {
                                            self.sessionStore.userSession?.profileImageUrl = url!
                                            NotificationCenter.default.post(name: NSNotification.Name("update_profile_image"), object: nil)
                                            self.loadingView = false
                                            self.showEditProfile = false
                                            
                                        } else {
                                            self.loadingView = false
                                        }
                                        
                                    })
                                }
                            }
                            
                            
                        }) {
                                HStack {
                                    Spacer()
                                    Text(LocalizedStringKey("Save changes")).foregroundColor(Color("ButtonFont")).fontWeight(.bold)
                                    Spacer()
                                }.padding().background(Color("ButtonBackground"))
                            
                        }.cornerRadius(5).shadow(radius: 10, x: 0, y: 10).padding()
                    }
                    
                    Group {
                        HStack {
                            if nextDateLoginUpdate < 300 {
                                Text(LocalizedStringKey("Less than a week has passed since the last login change, or the account was just created. Please wait")).foregroundColor(Color(.systemGray3)).padding(.top)
                            }
                            Text(LocalizedStringKey("User name:")).fontWeight(.bold)
                            Spacer()
                        }.padding(.top, 50)
                        // проверка для изменения логина
                        if nextDateLoginUpdate < 300 {
                            HStack {
                                TextField(LocalizedStringKey("Current username"), text: $name).padding(.top)
                                    .foregroundColor(Color(.systemGray2))
                                    .disabled(nextDateLoginUpdate < 300)
                            }.padding(.bottom).padding(.horizontal)
                            .background(Color(.systemGray5))
                            .cornerRadius(10)
                        } else {
                            HStack {
                                TextField(LocalizedStringKey("Current username"), text: $name).padding(.top)
                            }.padding(.bottom).padding(.horizontal).background(Color("textFieldBackground")).cornerRadius(10)
                        }
                        Button(action: {
                            let currentUser = Auth.auth().currentUser
                            if (currentUser != nil) {
                                self.loadingView = true
                                let id = currentUser!.uid
//                                добавить в коллекцию ниже параметры когда получитсвя везде обновлять инфо
//                                "username" : self.name, "keywords" : self.name.splitStringToArray()
                                Ref.FIRESTORE_COLLECTION_USERS.document(id).updateData(["username" : self.name, "keywords" : self.name.splitStringToArray()]) { (err) in
                                    //Конструкция: если err (ошибка) не nil, значит ест ьошибка и что-то пошло не так
                                    // если nil, значит все хорошо
                                    if let err = err {
                                        //делаем что-то если ошибка
                                        //например показываем надпись с сообщением об ошибке
                                        print("Error updating document: (err)")
                                        self.loadingView = false
                                    } else {
                                        self.sessionStore.userSession?.username = self.name
                                        self.sessionStore.userSession?.loginUpdateDate = Int(NSDate().timeIntervalSince1970)
                                        //обновление displayname
                                        let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
                                        changeRequest?.displayName = self.name
                                        changeRequest?.commitChanges { (error) in
                                            if error != nil {
                                                print(error!.localizedDescription)
                                                return
                                            } else {
                                                print("user has change his displayname to", Auth.auth().currentUser?.displayName)
                                            }
                                        }
                                        //то же самое только если все получилось
                                        print("Document successfully updated")
                                            self.loadingView = false
                                            self.showEditProfile = false
                                    }
                                }
                            }
                        }) {
                            if nextDateLoginUpdate < 300 {
                            HStack {
                                Spacer()
                                Text(LocalizedStringKey("Change username")).foregroundColor(Color(.systemGray6)).fontWeight(.bold)
                                Spacer()
                            }.padding(.top).padding(.bottom).background(Color(.systemGray3))
                            } else {
                                HStack {
                                    Spacer()
                                    Text(LocalizedStringKey("Change username")).foregroundColor(Color("ButtonFont")).fontWeight(.bold)
                                    Spacer()
                                }.padding(.top).padding(.bottom).background(Color("ButtonBackground"))
                            }
                            
                        }.cornerRadius(5).shadow(radius: 10, x: 0, y: 10).padding(.top).disabled(nextDateLoginUpdate < 300)
                        //конец блока обновления логина
                    }.padding(.horizontal)
                    Spacer()
                }.padding(.top)
                if self.loadingView == true {
                    VStack {
                        lottieView(filename: "loading-profile")
                    }.background(Color("textFieldBackground").edgesIgnoringSafeArea(.vertical))
                    
                }
            }.background(Color(UIColor.systemGray6).edgesIgnoringSafeArea(.vertical))
                .keyboardSensible($offsetValue).animation(.spring())
            .onTapGesture {
                closeKeyboard()
            }
                
            .onAppear() {
            let currentUser = Auth.auth().currentUser
            if (currentUser != nil) {
                
                if (self.loadImage == nil) {
                    getImageByName(name: currentUser?.uid) { (image) in
                        if image != nil {
                            self.loadImage = image
                        }
                    }
                }
                print(currentUser!.uid, "userid")
                let id = currentUser!.uid
                Api.User.loadUserById(id: id, onSuccess: {user in
                    if (user != nil) {
                        self.bio = user!.bio
                        self.name = user!.username
                    }
                })
            } else {
                print("nil in editProfileView")
            }
            
        }
        .sheet(isPresented: self.$showImagePicker, content: {
            ImagePicker2(showImagePicker: self.$showImagePicker, pickedImage: self.$image, imageData: self.$imageData)
        })
            .actionSheet(isPresented: self.$showChoose, content: {
                ActionSheet(title: Text(LocalizedStringKey("Take photo")), message: Text(LocalizedStringKey("Add photo from sourse")), buttons: [
                    .default(Text(LocalizedStringKey("Upload")), action: {
                        self.source = .photoLibrary
                        self.showImagePicker = true
                        //                        self.cameraViewModel.showImagePicker = true
                    }),
                    .default(Text(LocalizedStringKey("Take a photo")), action: {
                        self.source = .camera
                        self.showImagePicker = true
                        //                        self.cameraViewModel.showImagePicker = true
                        //                            self.showChoose = true
                    }),
                    .cancel(Text(LocalizedStringKey("Cancel")))
                ])
            })
        
    }
}
 

Комментарии:

1. Скорее всего, это связано с огромным представлением, попробуйте разделить его тело на более мелкие подвиды.

2. @Asperi может быть, создать функцию для этой операции? Может ли это помочь?

3. Аспери, скорее всего, прав. Это огромный взгляд. Чем больше вы отклоняетесь от него, тем меньше вы столкнетесь с этим. Да, перемещение этих 3 строк в отдельную функцию в отдельный файл должно исправить это … но … я предполагаю, что вы будете продолжать сталкиваться с этим, пытаясь делать все больше и больше.

Ответ №1:

Я думаю, что лучше изменить первую строку, как в приведенном ниже фрагменте кода:

 let date = Date()
let timeInterval = date.timeIntervalSince1970
let currentDate = Int(timeInterval)
 

Протестируйте это, я надеюсь, это поможет, иначе вам придется сделать другой код меньшим фрагментом

Комментарии:

1. кроме того, компилятор не может проверить это выражение в разумные сроки; попробуйте разбить выражение на отдельные подвыражения…. пусть date = Date() пусть timeInterval = date.timeIntervalSince1970 пусть currentDate = Int(timeInterval) пусть loginUpdateDate = sessionStore.UserSession?. loginUpdateDate пусть nextDateLoginUpdate = currentDate — loginUpdateDate

2. пожалуйста, разместите здесь весь код для этой функции.

3. Выполнено. Добавлена полная структура. Также хочу сказать — иногда это вызывает сбой, если я вызываю let loginUpdateDate = sessionStore.UserSession! .loginUpdateDate И я не знаю, насколько безопасно его развернуть. Попробовали if statesments и gurad. Вот почему я пытаюсь ответить на другой вопрос, может быть, у вас есть какие-либо идеи, как его развернуть.

Ответ №2:

Попробуйте преобразовать loginUpdateDate в int

 let currentDate = Int(Date().timeIntervalSince1970)
if let loginUpdateDate = sessionStore.userSession?.loginUpdateDate as? Int { 
let nextDateLoginUpdate : Int = currentDate - loginUpdateDate }
 

Такого рода предупреждения компилятора появляются каждый раз, когда Swift не ясно, какой тип объявления «let» или «var» будет перед компиляцией.

Необязательная цепочка (если позволено … как? Int { … } ) не обязательно, но это может быть безопаснее. В качестве альтернативы;

 let currentDate = Int(Date().timeIntervalSince1970)
let loginUpdateDate = Int(sessionStore.userSession?.loginUpdateDate)
let nextDateLoginUpdate = currentDate - loginUpdateDate
 

Редактировать 5 февраля 2021:
Вот еще одна идея: убедитесь, что currentDate и loginUpdate date являются двойными (я полагаю, что тип по умолчанию «timeInterval»), затем приведите к Int после операции, чтобы :

 let currentDate = Double(Date().timeIntervalSince1970)
let loginUpdateDate = Double(sessionStore.userSession?.loginUpdateDate)
let nextDateLoginUpdate = Int(currentDate - loginUpdateDate)
 

Комментарии:

1. извините за дилетантский вопрос (я пытаюсь), где в коде следует добавить это решение? Если я пытаюсь вывести на передний план за пределами тела var: some View { (23 строка) — он не может найти nextDateLoginUpdate «в области видимости, если я пытаюсь пройти его без него, я снова получаю «Компилятор не может проверить это выражение в разумные сроки; попробуйте разбить выражениена отдельные подвыражения». кажется, я пытаюсь вставить его в неправильное место в коде..

2. Ваш вопрос в порядке, и я думаю, мне следовало уточнить. В первом примере, когда loginUpdateDate успешно преобразуется в Int в условном коде, «следующий DateLoginUpdate будет находиться в области действия оператора if else.