Настройка текста UILabel из уведомления работает на симуляторе, но не на физическом устройстве - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть простое приложение, которое обновляет UILabel, когда пользователь нажимает на локальное push-уведомление. В симуляторе, когда я нажимаю на уведомление, вызывается applicationDidBecomeActive, и в этом у меня есть общий объект, ссылающийся на класс контроллера представления. Затем я вызываю функцию в этом классе, которая получает новую строку и устанавливает UILabel для указанной строки.

Это работает все время в симуляторе, но когда я загружаю приложение на свое устройство, оно работает пару раз, а затем останавливается.

Я знаю, что устройство обновляет строковое значение, потому что когда я переключаюсь на другое представление в приложении и переключаюсь обратно, UILabel теперь показывает правильно обновленное значение, но не при возврате из уведомления.

Кто-нибудь еще имел эту проблему, когда симулятор и физическое устройство ведут себя по-разному?

В соответствии с запросом приведен код, который, надеюсь, поможет:

Это из файла appDelagate.swift

func applicationDidBecomeActive(_ application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    fetchCurrentUnQuoteFromViewController()
    print("applicationDidBecomeActive has finished running.")
}

//Custom functions for the delagate
func setDefaultToTrue() {
    readyForNewUnQuote = true
    defaults.setValue(readyForNewUnQuote, forKey: "readyForNewUnQuote")
}

func fetchCurrentUnQuoteFromViewController() {
    let quoteViewController:QuoteViewController = window!.rootViewController as! QuoteViewController
    quoteViewController.getRandomGradient()
    quoteViewController.fetchRandomUnQuote()
}

В моем контроллере представления есть функции, которые вызываются из appDelagate

func getRandomGradient() {
    let randomNumber: Int = Int.random(in: 0 ... gradientArray.count - 1)
    QuoteGradient.image = UIImage(named: gradientArray[randomNumber])
}

func updateUI() {
    unQuoteLabel.text = defaults.string(forKey: "currentQuote")
}

Редактировать: я в основном добавил viewController.viewDidLoad () в качестве дополнительного вызова, и это, похоже, работает. Это плохой звонок? Это похоже на хакерский способ исправить ситуацию.

Хорошо, я думаю, что сузил это еще больше. У меня есть второй вид, который я пытаюсь использовать для страницы настроек. Если я просто продолжу первый просмотр с текстом цитаты, то при появлении уведомления я могу нажать на него, и он обновится до нового установленного текста.

Однако, если я перехожу к представлению настроек, а затем возвращаюсь к представлению цитаты, тогда, когда я нажимаю на уведомление, оно не обновляет текст, пока я не вернусь на страницу настроек и затем снова вернусь на страницу цитаты.

Я довольно новичок в разработке для iOS и не знаю, действительно ли переход к новому представлению что-то делает с общим объектом, который я создаю, или если он делает что-то еще, о чем я не знаю.

Редактировать 2: вот функция, которая срабатывает, когда пользователь нажимает на уведомление:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    setDefaultToTrue()
    print(defaults.value(forKey: "readyForNewUnQuote") ?? "Error")

    fetchCurrentUnQuoteFromViewController()

    print("response from notification was fired.")

    completionHandler()
}

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Я решил свою проблему!Проблема была с segues, который я использовал в раскадровке.

Вместо использования визуальных сегментов я изменил его так, чтобы при нажатии кнопки настроек я запускал здесь эту функцию, которая загружает вид из раскадровки и затем представляет его пользователю.Затем у меня есть другая кнопка на странице настроек, которая закрывает страницу.

@IBAction func settingsButtonAction(_ sender: UIButton) {
    let controller = storyboard?.instantiateViewController(withIdentifier: "SettingsViewController") as! SettingsViewController
    present(controller, animated: true, completion: nil)
}

Я понятия не имею, почему это вызвало проблему, так как я все еще новичок в разработке swift и iOS, но теперь я выиграл 'использовать раскадровку, чтобы представить пользователю различные взгляды.Сейчас я буду использовать только функции присутствия и отклонения.

0 голосов
/ 16 ноября 2018

Дайте это.Я не использовал локальные уведомления некоторое время, но, похоже, вы можете проверить делегата в Центре уведомлений для принятия предупреждения.

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    let handler = NotificationHandler()
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        handler.appDelegate = self
        let center = UNUserNotificationCenter.current()
        center.delegate = handler
        return true
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

    }
}

class NotificationHandler: NSObject, UNUserNotificationCenterDelegate {
    var appDelegate : AppDelegate?
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // Play sound and show alert to the user
        completionHandler([.alert,.sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {

        switch response.actionIdentifier {
        case UNNotificationDismissActionIdentifier:
            print("Dismiss Action")
        case UNNotificationDefaultActionIdentifier:
            print("we are launching")
            if let app = appDelegate,
                let root = app.window?.rootViewController as? ViewController{
                print("we have the info")
                root.titleLabel.text = response.notification.request.content.title
                root.bodyLabel.text = response.notification.request.content.body
            }
        case "Snooze":
            print("Snooze")
        case "Delete":
            print("Delete")
        default:
            print("Unknown action")
        }
        completionHandler()
    }
}


import UIKit
import UserNotifications

class ViewController: UIViewController {

    let center = UNUserNotificationCenter.current()

    lazy var titleLabel : UILabel = {
        let lbl = UILabel(frame: CGRect(x: 20, y: 0, width: self.view.bounds.width - 40, height: 50))
        lbl.textColor = .black
        lbl.font = UIFont.systemFont(ofSize: 20)
        lbl.numberOfLines = 0
        lbl.textAlignment = .center
        return lbl
    }()

    lazy var bodyLabel : UILabel = {
        let lbl = UILabel(frame: CGRect(x: 20, y: titleLabel.frame.maxY, width: self.view.bounds.width - 40, height: 50))
        lbl.textColor = .black
        lbl.font = UIFont.systemFont(ofSize: 20)
        lbl.numberOfLines = 0
        lbl.textAlignment = .center
        return lbl
    }()


    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(titleLabel)
        titleLabel.center = self.view.center
        titleLabel.text = "We are just getting started"
        self.view.addSubview(bodyLabel)

        let options: UNAuthorizationOptions = [.alert, .sound]
        center.requestAuthorization(options: options) {
            (granted, error) in
            if !granted {
                print("Something went wrong")
            }
        }

        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0) {
            self.center.removeAllDeliveredNotifications()
            self.center.removeAllPendingNotificationRequests()
            self.setNotificationWith(title: "Party", contentBody: "Party like it's 1999")
        }
    }

    func setNotificationWith(title:String,contentBody:String){
        let content = UNMutableNotificationContent()
        content.title = title
        content.body = contentBody
        content.sound = UNNotificationSound.default

        let date = Date(timeIntervalSinceNow: 60)
        let triggerDate = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute,.second,], from: date)

        let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate,
                                                    repeats: false)

        let identifier = "NotificationTest"
        let request = UNNotificationRequest(identifier: identifier,
                                            content: content, trigger: trigger)
        center.add(request, withCompletionHandler: { (error) in
            if let error = error {
                // Something went wrong
                print("we have an error \(error)")
            }
        })
    }
}
...