AppDelegate 从哪里来?如何返回上一个视图和访问实例

Where to from AppDelegate? how to go back to previous view and access instance

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

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

我的问题是,一旦来自第二个应用程序的响应到达 appdelegate 并到达 "return yes" 部分,我的主应用程序就会返回此 "PayView" 并且什么都不做。

那么我如何在我的 PayView 中使用我从 appdelegate 收到的响应对象以及现有的实例值?

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

因此,忽略全局并为 "payview" 创建一个新实例会导致所有先前存储的数据丢失。

我不是一个经验丰富的 iOS 程序员,只是暂时在别人身上工作 code.So,希望我能解释我的 issue/question。

如果我能得到一些有价值的意见就太好了:)

我的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

调用打开 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];

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

您可以在您的 PayView 中注册一个 NotificationCenter 观察器,并在收到响应时 post 来自您的 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