Просмотр проблем с иерархией - сначала инициализация из AppDelegate, позднее предотвращающая отображение UIAlertController [Цель C] - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть простое приложение, которое предлагает покупки в приложении для удаления рекламы и включает ряд дополнительных функций. В качестве фона, ViewController с именем InfoViewController является делегатом приложения SKPaymentTransactionObserver, а также отображает кнопку покупки, взаимодействует с iTunes Store, управляет процессом восстановления и т. Д. c.

. для распознавания прерванных транзакций я добавил TransactionObserver в свой AppDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    _infoVC = [[InfoViewController alloc] init];
   [[SKPaymentQueue defaultQueue] addTransactionObserver:_infoVC];

[...]

Если не был вызван транзакцияObserver AppDelegate, приложение не распознает, когда iTunes Store отправляет элемент в paymentQueue to updatedTransactions.

Для получения дополнительной информации InfoViewController запускается пользователем, нажимающим UIButton, и [self performSegueWithIdentifier:@"segueToUpgrade" sender:self] запускается из базового представления.

Это, кажется, вызывает некоторые проблемы, поскольку экземпляр InfoViewController уже был инициализирован из AppDelegate.

И поэтому это вызывает проблему ниже по течению, когда я пытаюсь отобразить UIAlertController на InfoViewController, но получает следующее предупреждение:

Warning: Attempt to present <UIAlertController: 0x1389f3800> on <InfoViewController: 0x139017680> whose view is not in the window hierarchy!

Удаление двух строк в didFinishLaunchingWithOptions решает проблему, но не решает проблему приложения, не распознавать, когда iTunes Store отправляет элемент в paymentQueue на updatedTransactions.

. Поэтому, как лучше всего убедиться, что AppDelegate может добавить InfoViewController в качестве transactionObserver, при этом позволяя UIAlertController будет отображаться, как только пользователь действительно перейдет к InfoViewController.

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

1 Ответ

0 голосов
/ 18 апреля 2020

Из прочитанного выше звучит так, будто вы пытаетесь заставить свой класс InfoViewController делать слишком много.

В своем коде вы утверждаете, что в вашем didFinishLaunchingWithOptions вы создаете экземпляр вашего InfoViewController. В дополнение к этому экземпляру также будет отдельный экземпляр вашего InfoViewController, который отображается для пользователя. Это автоматически создается для вашего представления, поэтому у вас есть две версии этого класса в игре:

  1. Прикреплено к вашему наблюдателю транзакции
  2. Прикреплено к вашему представлению

Когда вы пытаетесь использовать наблюдателя транзакции и вызываете UIAlertController, для отображения предупреждения требуется UIViewController (или производный класс). Однако у вашего обозревателя транзакций есть специальная версия, которую вы ему дали. Это не тот экземпляр, который отображается пользователю. Отсюда и ошибка, которая предупреждает вас, что она не связана с иерархией окон. AKA, пользователь не может видеть это.

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

Как найти самый верхний контроллер вида на iOS

Теперь вы можете получить самый верхний контроллер вида и использовать его для отобразить предупреждение (вместо себя). Это может решить вашу непосредственную проблему, но вы также создадите еще несколько проблем.

Как я уже упоминал в первом предложении, вы пытаетесь заставить ваш InfoViewController делать слишком много. С точки зрения программирования высокого уровня, вы будете нарушать принципы программирования разделения интересов и / или принцип единой ответственности.

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

Поскольку вы говорите, что вы новичок, они могут помочь получить дополнительную информацию о разделении интересов и принципе единой ответственности.

  1. https://softwareengineering.stackexchange.com/questions/38604/separation-of-concern-single-responsibilty-principle
  2. https://softwareengineering.stackexchange.com/questions/32581/how-do-you-explain-separation-of-concerns-to-others
  3. https://softwareengineering.stackexchange.com/questions/17100/clarify-the-single-responsibility-principle

Надеюсь, вышеизложенное поможет!

...