Куда из AppDelegate? как вернуться к предыдущему виду и получить доступ к экземпляру - PullRequest
1 голос
/ 05 июня 2019

У меня есть экземпляр в представлении под названием «PayView», и в то же время я делаю openURL, чтобы открыть отдельное приложение и передать ему некоторые данные.Это второе приложение обрабатывает информацию, которую я отправляю, и возвращает ответ.

На Appdelegate.m у меня есть этот handleOpenUrl, который получает ответ, отправленный вторым приложением.Как только я получу ответ, я хотел бы вернуться к своему «PayView» и использовать ответ, полученный от второго приложения, вместе с уже существующими значениями, которые у меня есть в экземпляре.

Моя проблема заключается в том, как толькоответ от второго приложения достигает appdelegate и достигает раздела «вернуть да», мое основное приложение возвращается к этому «PayView» и ничего не делает.

Так как же использовать объект ответа, полученный от appdelegate в моем PayView, вместе с уже существующими значениями экземпляра?

Я думал об использовании глобальной переменной для хранения экземпляра / объекта "payView" и запуска нового экземпляра из appdelegate для "Payview" и использования глобального вместе с ответом json из appdelegate.Тем не менее, я нашел много форумов, которые рекомендуют не использовать глобальные.

Таким образом, игнорирование глобального и создание нового экземпляра для "payview" приводит к потере всех ранее сохраненных данных.

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

Было бы здорово, если бы я мог получить некоторые ценные входные данные:)

Мой appdelegate.m выглядит следующим образом,

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    if (!url) {
        return NO;
    }

    // Unencode the URL's query string
    NSString *queryString = [[url query] stringByRemovingPercentEncoding];

    // Extract the JSON string from the query string
    queryString = [queryString stringByReplacingOccurrencesOfString:@"response=" withString:@""];

    // Convert the JSON string to an NSData object for serialization
    NSData *queryData = [queryString dataUsingEncoding:NSUTF8StringEncoding];

    // Serialize the JSON data into a dictionary
    NSDictionary* jsonObject = [NSJSONSerialization JSONObjectWithData:queryData options:0 error:nil];

    NSString *response = [jsonObject objectForKey:@"Result"]; //Get the response

    UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Result" message:response delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert1 show];

    //PayView *pdv = [[PayViewController alloc] init];

    //[pdv UseTransactionResult:jsonObject] ;


    return YES;
}

и вот как я называю openURL из PayView

[[UIApplication sharedApplication]openURL:[NSURL URLWithString:[NSString stringWithFormat:@"mysecondapp://v2/data/?request=%@",requestEncodedString]] options:@{} completionHandler:^(BOOL success) {
            if (success)
            {
                NSLog(@"Opened url");
            }
        }];

Редактировать 1:

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

Получатель:

[[NSNotificationCenter defaultCenter] addObserverForName:@"ActionIsComplete" object:nil queue:nil usingBlock:^(NSNotification *note){
        
        //Completed Action
        NSString *response = [note.userInfo objectForKey:@"Result"]; //Get the response
        NSLog(response);
        [self dismissViewControllerAnimated:YES completion:nil];
    
    }];

Однако,когда я пытаюсь сделать то же самое в следующем методе, я получаю сообщение об ошибке «нераспознанный селектор отправлен на экземпляр»

Получатель:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ReceiveActionIsComplete:) name:@"ActionIsComplete" object:nil];

-(void)ReceiveActionIsComplete:(NSNotification *) notification
{

    NSDictionary *jsonObject = (NSDictionary *)notification.userinfo;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ActionIsComplete" object:nil];

    Status = [jsonObject objectForKey:@"Status"];
    Result = [jsonObject objectForKey:@"Result"];

    NSLog([NSString stringWithFormat:@"%@%@",@"Status is: ", Status]);
    NSLog([NSString stringWithFormat:@"%@%@",@"Result is: ", Result]);
}

в обоих случаях мой отправитель в Appdelegate выглядит следующим образом.

Отправитель:

[[NSNotificationCenter defaultCenter] postNotificationName:@"ActionIsComplete" object:nil userInfo:jsonObject];

К вашему сведению: я также пытался отправить объект в объект вместо userInfo.

Так что я делаю не так?не могли бы вы мне помочь.

Вывод:

Отправитель: (AppDelegate.m)

[[NSNotificationCenter defaultCenter] postNotificationName:@"ActionIsComplete" object:nil userInfo:jsonObject];

Получатель: (PayView.m)

под - (void) viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ReceiveActionIsComplete:) name:@"ActionIsComplete" object:nil];

и функция для получения результатов

-(void)ReceiveActionIsComplete:(NSNotification *) notification
{

    NSDictionary *jsonObject = (NSDictionary *)notification.userInfo;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ActionIsComplete" object:nil];

    Status = [jsonObject objectForKey:@"Status"];
    Result = [jsonObject objectForKey:@"Result"];

    NSLog([NSString stringWithFormat:@"%@%@",@"Status is: ", Status]);
    NSLog([NSString stringWithFormat:@"%@%@",@"Result is: ", Result]);
}

1 Ответ

2 голосов
/ 05 июня 2019

Вы можете зарегистрировать наблюдателя NotificationCenter в вашем PayView и опубликовать уведомление от вашего AppDelegate, когда ответ будет получен.Посредством уведомления object вы можете переслать любую необходимую вам информацию.

Предположим, что вы определяете структуру с информацией, которую хотите передать:

struct PaymentConfirmation {
   let amount: Float
   let confirmationNumber: String
}

В вашем PayView:

class PayView: UIView {
...
   static let paymentProcessedNotification = NSNotification.Name("PayView.paymentProcessed")
   let paymentProcessedObserver: NSObjectProtocol?

   override func viewDidLoad() {
      super.viewDidLoad()
      paymentProcessedObserver = NotificationCenter.default.addObserver(
          forName: PayView.paymentProcessedNotification,
          object: nil,
          queue: .main) { [unowned self] (notification) in
              guard let confirmation = notification.object as PaymentConfirmation else { return }
              self.paymentProcessed(confirmation)
      }
   }

   deinit {
       NotificationCenter.default.removeObserver(paymentProcessedObserver)
   }

   func paymentProcessed(_ confirmation: PaymentConfirmation) {
      // do stuff
   }

Затем в вашем AppDelegate:

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
        // do stuff required with the callback URL
        let confirmation = PaymentConfirmation(
            amount: 3.0, 
            confirmationNumber: "Pay830da08.8380zSomething")
        NotificationCenter.default.post(
            name: PayView.paymentProcessedNotification, 
            object: confirmation)
    }

Для получения дополнительной информации, проверьте https://medium.com/ios-os-x-development/broadcasting-with-nsnotification-center-8bc0ccd2f5c3

...