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
我在名为 "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