• IOS:程序的退出、App间的跳转


    今天在做一个音乐播放器的项目,发现这个点击退出程序的功能不能实现终于找到了一些有用的资料,就去网上看了半天资料,下面是退出程序的代码:

    在动画里面可以自己添加一些,动画,达到相应的效果。

     
       AppDelegate *app = [UIApplication sharedApplication].delegate;
        UIWindow *window = app.window;
        [UIView animateWithDuration:1.0f animations:^{
            window.alpha = 0;
            window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
        } completion:^(BOOL finished) {
            exit(0);
        }];

    在一个程序中打开另一个应用程序 参考 

    应用之间跳转的原理:

    在iOS中打开一个应用程序只需要拿到这个应用程序的协议头即可,所以我们只需配置应用程序的协议头即可。

    假设有应用A应用B两个应用,现在需要从应用A跳转到应用B中。

    • 原理:通过设置跳转到应用B的URL Schemes(自定义的协议头),应用B将其自身“绑定”到一个自定义URL Schemes上,就可以从应用A中利用应用B的URL Schemes启动应用B了。

    具体怎么做呢,下面一步步来教你,先来个简单点的:从应用A跳转到应用B。设置App-B的URL Schemes

    应用A跳转到应用B
    1. 首先我们用Xcode创建两个iOS应用程序项目,项目名称分别为App-A、App-B。

    2. 选择项目App-B -> TARGETS -> Info -> URL Types -> URL Schemes,设置App-B的URL Schemes为AppB。

    在应用程序App-A中添加一个用来点击跳转的Button,并监听点击事件,添加跳转代码。

    //添加跳转按钮
    - (IBAction)jumpToAppB:(id)sender {
       // 1.获取应用程序App-B的URL Scheme
       NSURL *appBUrl = [NSURL URLWithString:@"AppB://"];
    
       // 2.判断手机中是否安装了对应程序
       if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
           // 3. 打开应用程序App-B
           [[UIApplication sharedApplication] openURL:appBUrl];
       } else {
           NSLog(@"没有安装");
       }
    }

    注意:

    1. 如果是iOS9之前的模拟器或是真机,那么在相同的模拟器中先后运行App-B、App-A,点击按钮,就可以实现跳转了。

    2. 如果是iOS9之后的模拟器或是真机,那么则需要再在应用程序App-A中将App-B的URL Schemes添加到白名单中,原因和做法如下。

      • iOS9引入了白名单的概念。

      • 在iOS9中,如果使用 canOpenURL:方法,该方法所涉及到的 URL Schemes 必须在"Info.plist"中将它们列为白名单,否则不能使用。key叫做LSApplicationQueriesSchemes ,键值内容是对应应用程序的URL Schemes。

    具体做法就是在App-A的Info文件中,添加LSApplicationQueriesSchemes数组,然后添加键值为AppB的字符串。

     

     
    添加LSApplicationQueriesSchemes数组,然后添加键值为AppB的字符串

    添加白名单之后在相同的模拟器中先后运行App-B、App-A,点击按钮,就可以实现跳转了。

    假设有两个程序如下: App_a、App_b,我们要是现在 App_a 里触发某个事件去打开 App_b,具体实现如下所示:

    建立一个新的项目 App_a 步骤如下所示:

    在 App_a 中设置跳转按钮,如下所示:

    并做好关联,在 ViewController.m 中的代码如下所示:

    #import "ViewController.h"
    #import "AppDelegate.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    // 跳转到 App——b
    - (IBAction)backToApp_b_method:(UIButton *)sender {
        
        // 1.获取应用程序App-B的URL Scheme
        // 下面代码是跳转的关键代码;AppB:// 就是我们第二个 APP 的 URL Schemes 。
        NSString *urlStr = @"AppB://";
        NSURL *url = [NSURL URLWithString:urlStr];
        
        // 2.判断手机中是否安装了对应程序
        if ([[UIApplication sharedApplication] canOpenURL:url]) {
            // 3. 打开应用程序App-B
            [[UIApplication sharedApplication] openURL:url];
        } else {
            NSLog(@"没有安装");
        }
    
        
    }
    
    // 退出 App——a 程序
    - (IBAction)exitApp_a_method:(UIButton *)sender {
        
        AppDelegate *app = [UIApplication sharedApplication].delegate;
        UIWindow *window = app.window;
        [UIView animateWithDuration:1.0f animations:^{
            window.alpha = 0;
            window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
        } completion:^(BOOL finished) {
            exit(0);
        }];
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end

    在 App_a 的 info 文件中设置如下:

    我们这里已经将错误的 URL  Schemes  改为正确的 如下所示:

    在 App_b 中也做如上的设置,新建 App_b ,设置 info.plist 文件, 在 info.plist 文件里添加   LSApplicationQueriesSchemes  数组,在数组中插入一个字符串元素为 App_a 就是一个能够打开的 App 的名字, 在 URL Types 里新增 URL (AppB) 并绑定 App_b 的 bundleID (com.jw.AppB) 如下图所示。

    在 App_b 的 Main 文件里也做几个按钮,用于跳转到 App_a 中 并做好sb 与代码的关联,代码如下:

    #import "ViewController.h"
    #import "AppDelegate.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    
    // 跳转到 App——a 程序
    - (IBAction)backToApp_a_method:(UIButton *)sender {
        
        // 下面代码是跳转的关键代码;App_a:// 就是我们第一个 APP 的 URL Schemes 。
        NSString *urlStr = @"AppA://";
        NSURL *url = [NSURL URLWithString:urlStr];
        [[UIApplication sharedApplication] openURL:url];
    }
    
    // 退出 App——b 程序
    - (IBAction)exitApp_b_method:(UIButton *)sender {
        
        AppDelegate *app = [UIApplication sharedApplication].delegate;
        UIWindow *window = app.window;
        
        [UIView animateWithDuration:1.0f animations:^{
           
            window.alpha = 0;
            window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
            
        } completion:^(BOOL finished) {
            
            exit(0);
            
        }];
    }
    
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end

    此时运行两个 App ,我们在 App_a 的页面中点击跳转到 App_b 就能够实现页面的跳转了。

    应用App_a跳转到应用App_b的特定界面

    很多时候,我们做应用程序之间的跳转并不只是跳转到其他程序就可以了,而是要跳转到其他程序的特定页面上。比如我们在浏览网页时,会有分享到微信朋友圈或是分享给微信朋友,这就需要跳转到微信朋友圈界面或是微信朋友选择界面。

    具体如何做呢?

     1、首先我们先来为App-b搭建两个页面 FFPageViewController 和 HHPageViewController 。这里用导航控制器 Push 两个 ViewController,通过Push 来进入 FFPaeViewControler 所以将 FFPageViewController 的页面标示绑定为 FFPage,通过Storyboard Segue设置HHPageViewController的标识符绑定,"HHPage"。之所以这样做,是为了实现两种技术下的页面跳转。如下所示:

    代码为:

    Appdelegate.m 文件修改代码如下:

    #import "AppDelegate.h"
    #import "ViewController.h"
    #import "FFPageViewController.h"
    
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        return YES;
    }
    
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
        // 1.获取导航栏控制器
        UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
        // 2.获得主控制器
        ViewController *mainVc = [rootNav.childViewControllers firstObject];
        
        // 保存完整的App-A的URL给主控制器
        mainVc.urlString = url.absoluteString;
        
        // 3.每次跳转前必须是在跟控制器(细节)
        [rootNav popToRootViewControllerAnimated:NO];
        
        // 4.根据字符串关键字来跳转到不同页面
        if ([url.absoluteString containsString:@"FFPage"]) { // 跳转到应用App_b的FFPage页面
            
            UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"FFPageViewController" bundle:[NSBundle mainBundle]];
            
            FFPageViewController * ffPage = [storyboard instantiateViewControllerWithIdentifier:@"FFPageViewController"];
            
            ffPage.urlString = mainVc.urlString;//传递原来的App 的 URL scheme
            [mainVc.navigationController pushViewController:ffPage animated:YES];
            
        } else if ([url.absoluteString containsString:@"HHPageSegue"]) { // 跳转到应用App_b的HHViewController页面
            
            // 根据segue标示进行跳转
            [mainVc performSegueWithIdentifier:@"HHPageSegue" sender:nil];
            
        }
    
        return YES;
        
    }
    
    @end

    ViewController.h文件修改

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    // 用来保存App_a完整的URL
    @property (nonatomic, copy) NSString *urlString;
    
    @end

    ViewController.m文件修改

    #import "ViewController.h"
    #import "AppDelegate.h"
    #import "HHViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    
    // 跳转到 App——a 程序
    - (IBAction)backToApp_a_method:(UIButton *)sender {
        
        // 1.获取应用程序App-A的URL Scheme
        // 下面代码是跳转的关键代码;App_a:// 就是我们第一个 APP 的 URL Schemes 。
        NSString *urlStr = @"AppA://";
        NSURL *url = [NSURL URLWithString:urlStr];
        
        // 2.判断手机中是否安装了对应程序
        if ([[UIApplication sharedApplication] canOpenURL:url]) {
            // 3. 打开应用程序App-A
            [[UIApplication sharedApplication] openURL:url];
        } else {
            NSLog(@"没有安装");
        }
    
        
    }
    
    // 退出 App——b 程序
    - (IBAction)exitApp_b_method:(UIButton *)sender {
        
        AppDelegate *app = (id)[UIApplication sharedApplication].delegate;
        UIWindow *window = app.window;
        
        [UIView animateWithDuration:1.0f animations:^{
           
            window.alpha = 0;
            window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
            
        } completion:^(BOOL finished) {
            
            exit(0);
            
        }];
    }
    
    // 使用 segue 进行跳转
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.identifier isEqualToString:@"HHPageSegue"]) {
            // 获得将要跳转的界面HHViewController的控制器
            HHViewController *HHPage = segue.destinationViewController;
            // 保存完整的App_a的URL给跳转界面HHViewController,方便后期能够返回的操作等....这里不再写了
            HHPage.urlString = self.urlString;
        }
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    @end

    FFPageViewController.h 文件

    #import <UIKit/UIKit.h>
    
    @interface FFPageViewController : UIViewController
    
    // 用来保存App_a完整的URL
    @property (nonatomic, copy) NSString *urlString;
    
    @end

    FFPageViewController.m 文件

    #import "FFPageViewController.h"
    
    @interface FFPageViewController ()
    
    @end
    
    @implementation FFPageViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }
    
    // 返回 App_a 程序
    - (IBAction)backToApp_aMethod:(UIButton *)sender {
        
        // 1.拿到对应应用程序的 URL Schemes
        NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject];
        NSString *urlString = [urlSchemeString stringByAppendingString:@"://"];
        
        // 1.获取对应应用程序的URL
        NSURL *url = [NSURL URLWithString:urlString];
        
        // 2.判断是否可以打开
        if ([[UIApplication sharedApplication] canOpenURL:url]) {
            [[UIApplication sharedApplication] openURL:url];
        }else {
            NSLog(@"没有安装原来的程序,着说不通啊,你是咋跳转过来的昂?");
        }
    
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    /*
    #pragma mark - Navigation
    
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
    
    @end
     

    在 HHViewController.h 文件里添加属性 urlString 字段。

    在 HHViewController.m 文件里添加如下代码,并与 StoryBoard 文件关联:

    // 返回 App_a 程序
    - (IBAction)backTo_App_aMethod:(UIButton *)sender {
        
        // 1.拿到对应应用程序的URL Scheme
        NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject];
        NSString *urlString = [urlSchemeString stringByAppendingString:@"://"];
        
        // 1.获取对应应用程序的URL
        NSURL *url = [NSURL URLWithString:urlString];
        
        // 2.判断是否可以打开
        if ([[UIApplication sharedApplication] canOpenURL:url]) {
            [[UIApplication sharedApplication] openURL:url];
        }else {
            NSLog(@"没有安装原来的程序,着说不通啊,你是咋跳转过来的昂?");
        }
    
    }

    2、然后再在 App_a 中添加一些用来跳转的页面,并进行关联,如下所示:

    3、注意,从应用程序 App_b 跳回 App_a 的实现原理如下:

    步骤分析:

    1. 我们想要从应用B再跳转回应用A,那么在跳转到应用B的时候,还应将应用A的URL Schemes传递过来。这样我们才能判断应该跳转回哪个应用程序。

      • 这样我们指定一个传递URL的规则:协议头://应用B的URL Schemes?应用A的URL Schemes。即:AppB://Page1?AppA

      • 说明:

        • AppB是跳转过来的应用App-B的URL Schemes;

        • Page1是用来区别跳转页面的标识;

        • ? 是分割符;

        • AppA是跳转回的应用App-A的URL Schemes

    2. 我们根据传递来的数据,进行反跳回去。

      1. 之前我们在应用App-B中通过AppDelegate执行不同页面的跳转。在对应方法中我们可以拿到完整的URL,在主控制器ViewController中设定一个属性,将该URL保存在主控制器中。

      2. 在主控制器中我们可以通过- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;方法获取将要跳转的页面控制器。

      3. 在将要跳转的页面控制器中定义一个属性,用于接受、截取出跳转回的应用(即App-A)的URL Schemes,执行跳转。

    4、实现效果图如下:

     首先运行两个程序,保证安装成功。

    5、资源链接,记得点赞!

     
     
     
  • 相关阅读:
    用大白话谈谈XSS与CSRF
    Lenet5设计理解——咬文嚼字系列
    【java设计模式】之 责任链(chain of resposibility)模式
    【java设计模式】之 代理(Proxy)模式
    【java设计模式】之 建造者(Builder)模式
    【java设计模式】之 模板方法(Template Method)模式
    【java设计模式】之 抽象工厂(Abstract Factory)模式
    【java设计模式】之 工厂(Factory)模式
    浅谈Arrays.asList()方法的使用
    分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)
  • 原文地址:https://www.cnblogs.com/benpaobadaniu/p/5093899.html
Copyright © 2020-2023  润新知