#ios #swift #xcode
#iOS #swift #xcode
Вопрос:
Я довольно новичок в swift, я пытаюсь реализовать функцию, согласно которой при входе пользователя в систему он будет попадать непосредственно на домашнюю страницу, а не на страницу входа в систему при каждом повторном открытии приложения.
Я взял ссылку на учебное пособие: https://www.youtube.com/watch?v=gjYAIXjpIS8amp;t=146s . и я реализовал логическую проверку is logged in, как и он, но я почему-то столкнулся с проблемой повторного открытия домашней страницы во время входа в систему. У меня сообщение об ошибке: [Presentation] Attempt to present <UITabBarController: 0x7fa68102ea00> on <IFTTT.ViewController: 0x7fa67fe0c150> (from <IFTTT.ViewController: 0x7fa67fe0c150>) whose view is not in the window hierarchy.
Вот как мой класс контроллера страницы входа: (который является точкой входа при открытии приложения) Я попытался представить как учебное пособие и выполнить начало, и оба отображают одно и то же сообщение об ошибке выше
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if isLoggedIn() {
performSegue(withIdentifier: "logInJump", sender: nil)
}
}
fileprivate func isLoggedIn() -> Bool {
print("logged in status: (UserDefaults.standard.bool(forKey: "isLoggedIn"))")
return UserDefaults.standard.bool(forKey: "isLoggedIn")
}
@IBAction func signInButton(_ sender: Any) {
print("sign in tapped")
if let appURL = URL(string: "http://vocation.cs.umd.edu/flask/register") {
UIApplication.shared.open(appURL) { success in
if success {
print("The URL was delivered successfully.")
} else {
print("The URL failed to open.")
}
}
} else {
print("Invalid URL specified.")
}
}
}
// button broder width
@IBDesignable extension UIButton {
@IBInspectable var borderWidth: CGFloat {
set {
layer.borderWidth = newValue
}
get {
return layer.borderWidth
}
}
@IBInspectable var cornerRadius: CGFloat {
set {
layer.cornerRadius = newValue
}
get {
return layer.cornerRadius
}
}
@IBInspectable var borderColor: UIColor? {
set {
guard let uiColor = newValue else { return }
layer.borderColor = uiColor.cgColor
}
get {
guard let color = layer.borderColor else { return nil }
return UIColor(cgColor: color)
}
}
}
и это моя беспорядочная доска объявлений и переходы:
доска объявлений
Я попытался добавить навигационный контроллер, который попадает в точку входа приложения, и он выполняет isLoggedIn так же, как и класс view controller, но он также имеет ту же ошибку.
Может кто-нибудь рассказать мне, как это исправить или какие-либо другие лучшие методы? Я чувствовал, что я слепой, так как я только что начал изучать swift. Спасибо!
Ответ №1:
Для выполнения перехода необходимо выполнить поток запроса. Поскольку ваш вызов performSegue
в viewDidLoad()
what происходит, ваш вызов вызывается до того, как все будет загружено, поэтому вам нужно ввести некоторое отставание.
Потоки иногда называют легковесными процессами, потому что они имеют свой собственный стек, но могут получать доступ к общим данным. Поскольку потоки используют то же адресное пространство, что и процесс, и другие потоки внутри процесса, эксплуатационные расходы на связь между потоками низкие, что является преимуществом
Асинхронная функция будет ожидать выполнения обещания, а асинхронная функция всегда будет возвращать обещание. Обещание, возвращаемое асинхронной функцией, будет разрешено с любым значением, возвращаемым функцией
Короче говоря, вам нужно дождаться, пока все будет загружено в память, и если вы вызываете функции из основного стека / потока, например viewDidLoad()
, тогда есть большая вероятность, что он еще не загружен в память. Это означает, logInJump
что segue не существует в этот момент в этом контроллере представления, поэтому ваша ошибка.
Другая возможность заключается в том, что у вас нет правильного идентификатора просмотра / перехода, но это должно было вызвать другую ошибку.
Кроме того, измените отправителя с nil
на self
. На самом деле в этом нет необходимости, но я всегда использовал self
over nil
// change to desired number of seconds should be higher then 0
let when = DispatchTime.now() 0.2
if isLoggedIn() {
DispatchQueue.main.asyncAfter(deadline: when) {
self.dismiss(animated: true, completion: nil)
self.performSegue(withIdentifier: "logInJump", sender: nil)
}
}
Комментарии:
1. Большое вам спасибо за ваши подробные инструкции и решение моей проблемы! Это работает, и я больше понимаю об этих методах, но когда я заменяю свою часть вашим кодом, я иногда получаю несколько (довольно много) предупреждений: [Assert] Не может быть вызван с помощью asCopy = NO в неосновном потоке. Хотя это, кажется, не противоречит функциональности, но есть ли способ это исправить? Еще раз спасибо за вашу помощь! Я очень ценю это!