【问题标题】:Where to from AppDelegate? how to go back to previous view and access instance从 AppDelegate 到哪里?如何返回上一个视图和访问实例
【发布时间】:2019-06-05 01:26:19
【问题描述】:

我在一个名为“PayView”的视图中有一个实例,同时我正在执行 openURL 以打开一个单独的应用程序并将一些数据传递给它。第二个应用程序处理我发送的信息并返回响应。

在 Appdelegate.m 我有这个 handleOpenUrl,它接收第二个应用发送的响应。收到回复后,我想返回“PayView”并使用从第二个应用收到的回复以及我在实例中已有的值。

我的问题是,一旦第二个应用程序的响应到达 appdelegate 并到达“返回是”部分,我的主应用程序就会返回此“PayView”并且什么也不做。

那么,如何使用我在 PayView 上从 appdelegate 收到的响应对象以及已经存在的实例值?

我考虑使用全局变量来存储“payView”实例/对象,并从 appdelegate 为“Payview”启动一个新实例,并将全局变量与来自 appdelegate 的响应 json 一起使用。但是,我发现许多论坛建议不要使用 global.

因此,忽略全局并为“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;
}

这就是我从 PayView 调用 open url 的方式

[[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];
    
    }];

但是,当我尝试在以下方法中执行相同操作时,我收到错误 "unrecognized selector sent to instance"

接收者:

[[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];

仅供参考:我也尝试在 object 而不是 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]);
}

【问题讨论】:

  • 您可能没有注意到,但在第二种情况下,您正在使用带有“ReceivedActionComplete”的@选择器,但您指向的函数称为“ReceivedCayanActionIsComplete”。注意@选择器中缺少的单词“Cayan”。
  • @ekscrypto 这是一个错字,我重命名了函数以匹配选择器,但问题仍然存在。然后我发现我的选择器语法错误,它缺少一个冒号:用正确的语法编辑了我的代码,它运行良好。非常感谢您的宝贵意见:)
  • 很高兴为您提供帮助,别忘了将答案标记为您的解决方案 :)

标签: objective-c appdelegate url-scheme


【解决方案1】:

您可以在您的 PayView 中注册 NotificationCenter 观察者,并在收到响应时从您的 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

【讨论】:

  • 嗨@ekscrypto,非常感谢。这真的很有帮助。我只有一个问题,并对我原来的问题“编辑 1”进行了编辑。如果我做错了什么,请告诉我。谢谢
猜你喜欢
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多