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、資源鏈接,記得點贊!

 

 

 

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM