在 iOS 与 Android 上实现 React Native 应用深度链接,使得应用可以通过
我们生活在一个万物兼可分享的年代,而分享的过程,几乎最终都会分享某一个链接,那么,作为开发者,最常遇到的问题中应该包括如何通过一个URL地址快速的打开App,并导航至特定的页面。

什么是深度链接(Deep Link)
深度链接是一项可以让一个App通过一个URL地址打开,之后导航至特定页面或者资源,或者展示特定UI的技术,Deep 的意思是指被打开的页面或者资源并不是App的首页,最常使用到的地方包括但远远不限于 Push Notification、邮件、网页链接等。

其实这个技术在很久很久以前就已经存在了,鼠标点击一下 mailto:pantao@parcmg.com 这样的链接,系统会打开默认的邮件软件,然后将 pantao@parcmg.com 这个邮箱填写至收件人输入栏里,这就是深度链接。

本文将从零开始创建一个应用,让它支持通过一个如 deep-linking://articles/{ID} 这样的 URL 打开 文章详情 页面,同时加载 {ID} 指定的文章,比如:deep-linking://articles/4 将打开 ID 为 4 的文章详情页面。

深度链接解决了什么问题?
网页链接是无法打开原生应用的,如果一个用户访问你的网页中的某一个资源,他的手机上面也已经安装了你的应用,那么,我们要如何让系统自动的打开应用,然后在应用中展示用户所访问的那一个页面中的资源?这就是深度链接需要解决的问题。

实现深度链接的不同方式
有两种方式可以实现深度链接:

URL scheme
Universal links
前端是最常见的方式,后者是 iOS 新提供的方式,可以一个普通的网页地址链接至App的特定资源。

本文将创建一个名为 DeepLinkingExample 的应用,使得用户可以通过打开 deep-linking://home 以及 deep-linking://articles/4 分别打开 App 的首页以及 App 中 ID 为 4 的文章详情页面。

react-native init DeepLinkingExample
cd DeepLinkingExample
安装必要的库
紧跟 TypeScript 大潮流,我们的 App 写将使用 TypeScript 开发。

yarn add react-navigation react-native-gesture-handler
react-native link react-native-gesture-handler
我们将使用 react-navigation 模块作为 App 的导航库。

添加 TypeScript 相关的开发依赖:

yarn add typescript tslint tslint-react tslint-config-airbnb tslint-config-prettier ts-jest react-native-typescript-transformer -D
yarn add @types/jest @types/node @types/react @types/react-native @types/react-navigation @types/react-test-renderer
添加 tsconfig.json:{"compilerOptions": {"target": "es2017",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */"module": "es2015",                       /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */"lib": [                                  /* Specify library files to be included in the compilation:  */"es2017","dom"],"resolveJsonModule": true,"allowJs": false,                         /* Allow javascript files to be compiled. */"skipLibCheck": true,                     /* Skip type checking of all declaration files. */"jsx": "react-native",                    /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */"declaration": true,                      /* Generates corresponding '.d.ts' file. */"sourceMap": true,                        /* Generates corresponding '.map' file. */"outDir": "./lib",                        /* Redirect output structure to the directory. */"removeComments": true,                   /* Do not emit comments to output. */"noEmit": true,                           /* Do not emit outputs. *//* Strict Type-Checking Options */"strict": true,                           /* Enable all strict type-checking options. */"noImplicitAny": true,                    /* Raise error on expressions and declarations with an implied 'any' type. */"strictNullChecks": true,                 /* Enable strict null checks. */"strictFunctionTypes": true,              /* Enable strict checking of function types. */"noImplicitThis": true,                   /* Raise error on 'this' expressions with an implied 'any' type. */"alwaysStrict": true,                     /* Parse in strict mode and emit "use strict" for each source file. *//* Additional Checks */"noUnusedLocals": true,                   /* Report errors on unused locals. */"noUnusedParameters": true,               /* Report errors on unused parameters. */"noImplicitReturns": true,                /* Report error when not all code paths in function return a value. */"noFallthroughCasesInSwitch": true,       /* Report errors for fallthrough cases in switch statement. *//* Module Resolution Options */"moduleResolution": "node",               /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */"baseUrl": "./",                          /* Base directory to resolve non-absolute module names. */"paths": {                                /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */"*": ["*.android","*.ios","*.native","*.web","*"]},"typeRoots": [                            /* List of folders to include type definitions from. */"@types","../../@types"],// "types": [],                           /* Type declaration files to be included in compilation. */"allowSyntheticDefaultImports": true,     /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */// "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. *//* Experimental Options */"experimentalDecorators": true,           /* Enables experimental support for ES7 decorators. */"emitDecoratorMetadata": true             /* Enables experimental support for emitting type metadata for decorators. */},"exclude": ["node_modules","web"]
}

添加 tslint.json 文件

{"defaultSeverity": "warning","extends": ["tslint:recommended", "tslint-react","tslint-config-airbnb","tslint-config-prettier"],"jsRules": {},"rules": {"curly": false,"function-name": false,"import-name": false,"interface-name": false,"jsx-boolean-value": false,"jsx-no-multiline-js": false,"member-access": false,"no-console": [true, "debug", "dir", "log", "trace", "warn"],"no-empty-interface": false,"object-literal-sort-keys": false,"object-shorthand-properties-first": false,"semicolon": false,"strict-boolean-expressions": false,"ter-arrow-parens": false,"ter-indent": false,"variable-name": [true,"allow-leading-underscore","allow-pascal-case","ban-keywords","check-format"],"quotemark": false},"rulesDirectory": []
}

添加 .prettierrc 文件:

{"parser": "typescript","printWidth": 100,"semi": false,"singleQuote": true,"trailingComma": "all"
}

编写我们的应用
在项目根目录下创建一个 src 目录,这个将是项目原代码的目录。

添加 src/App.tsx 文件

import React from 'react'import { createAppContainer, createStackNavigator } from 'react-navigation'import About from './screens/About'
import Article from './screens/Article'
import Home from './screens/Home'const AppNavigator = createStackNavigator({Home: { screen: Home },About: { screen: About, path: 'about' },Article: { screen: Article, path: 'article/:id' },},{initialRouteName: 'Home',},
)const prefix = 'deep-linking://'const App = createAppContainer(AppNavigator)const MainApp = () => <App uriPrefix={prefix} />export default MainApp
添加 src/screens/Home.tsx 文件
import React from 'react';
添加 src/screens/About.tsx
import React from 'react'import { StyleSheet, Text, View } from 'react-native'import { NavigationScreenComponent } from 'react-navigation'interface IProps {}interface IState {}const AboutScreen: NavigationScreenComponent<IProps, IState> = props => {return (<View style={styles.container}><Text style={styles.title}>About Page</Text></View>)
}AboutScreen.navigationOptions = {title: 'About',
}export default AboutScreenconst styles = StyleSheet.create({container: {},title: {},
})
添加 src/screens/Article.tsx
import React from 'react'import { StyleSheet, Text, View } from 'react-native'import { NavigationScreenComponent } from 'react-navigation'interface NavigationParams {id: string
}const ArticleScreen: NavigationScreenComponent<NavigationParams> = ({ navigation }) => {const { params } = navigation.statereturn (<View style={styles.container}><Text style={styles.title}>Article {params ? params.id : 'No ID'}</Text></View>)
}ArticleScreen.navigationOptions = {title: 'Article',
}export default ArticleScreenconst styles = StyleSheet.create({container: {},title: {},
})

配置 iOS
打开 ios/DeepLinkingExample.xcodeproj:

open ios/DeepLinkingExample.xcodeproj
点击 Info Tab 页,找到 URL Types 配置,添加一项:

identifier:deep-linking
URL Schemes:deep-linking
其它两项留空
打开项目跟目录下的 AppDelegate.m 文件,添加一个新的 import:

#import “React/RCTLinkingManager.h”
然后在 @end 前面,添加以下代码:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}

至此,我们已经完成了 iOS 的配置,运行并测试是否成功。

react-native run-ios
打开 simulator 之后,打开 Safari 浏览器,在地址栏中输入:deep-linking://article/4 ,你的应用将会自动打开,并同时进入到 Article 页面。

同样的,你还可以在命令行工具中执行以下命令:

xcrun simctl openurl booted deep-linking://article/4

配置 Android
要为Android应用也创建 External Linking,需要创建一个新的 intent,打开 android/app/src/main/AndroidManifest.xml,然后在 MainActivity 节点添加一个新的 intent-filter:

<application ...><activity android:name=".MainActivity" ...>...<intent-filter><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><data android:scheme="deep-linking" /></intent-filter>...</activity>
</application>

Android 只需要完成上面的配置即可。

执行:

react-native run-android
打开系统浏览器,输入:

deep-linking://article/4
系统会自动打开你的应用,并进入 Article 页面

也可以在命令行工具中使用以下命令打开:

adb shell am start -W -a android.intent.action.VIEW -d “deep-linking://article/3” com.deeplinkingexample;

附录

面试题持续更新记得关注我哦!
不同的圈子就有不同的学习方式 ;
(qq群搜索):651612063 群密码:111 进群文件可以直接获取大厂面试题

点击进群

在 iOS 与 Android 上实现 React Native 应用深度链接,通过 URL 打开到指定页面相关推荐

  1. React Native 应用深度链接是如何通过 URL打开到指定页面

    什么是深度链接(Deep Link) 深度链接是一项可以让一个App通过一个URL地址打开,之后导航至特定页面或者资源,或者展示特定UI的技术,Deep 的意思是指被打开的页面或者资源并不是App的首 ...

  2. react native 实现浏览器唤醒APP并跳转指定页面

    推荐使用react-navigation导航器提供的Deep linking 功能来实现. 根据官方的例子来一步步实现: 假设我们要实现在浏览器上通过点击URI(mychat://chat/Eric) ...

  3. 如何在iOS上运行React Native应用

    by Soujanya PS 通过Soujanya PS 如何在iOS上运行React Native应用 (How to run a React Native app on iOS) I recent ...

  4. Microsoft将在UWP上支持React Native,同时为VS Code添加工具软件

    Microsoft和Facebook日前宣布React Native的下一个目标平台是Universal Windows Platform(UWP). 对于已经在多个设备平台上使用React Nati ...

  5. 在windows上搭建React Native开发环境

    最近要学习React Native,但是在window上搭建开发环境的时候遇到了些问题,以至于一直没有搭建好开发环境. React Native相关项目及文档: react-native的GitHub ...

  6. Android手机teams,在iOS和Android上自定义Microsoft Teams体验的三种最佳方法

    以下是您可以在iOS和Android上自定义Microsoft Teams应用程序以使其成为自己的三种方法 1. 开启黑暗模式,以便iOS和Android上的小组中的消息和其他内容更易于理解和阅读 2 ...

  7. android类似于ios剪切框图片,不必羡慕 iOS,Android 上也有这些好用的截图处理工具...

    原标题:不必羡慕 iOS,Android 上也有这些好用的截图处理工具 在截图编辑和 GIF 制作方面,iOS 平台有诸多独占且优秀的应用可以使用,例如利用 Picsew 截图拼接.Annotable ...

  8. 混合开发架构|Android工程集成React Native、Flutter、ReactJs

    混合开发架构|Android工程集成React Native.Flutter.ReactJs 架构设计说明 创建安卓原生工程 创建Flutter 集成嵌入原生工程 创建React Native 解决R ...

  9. 在Linux上使用ffmpeg摆脱DTS / AC3音频,以在iOS或Android上播放MKV文件

    I encountered the problem on iPhone that MKV video files with AC3 are played with no sound. The OPla ...

最新文章

  1. 9.9学python靠谱吗-走进小学教材,Python何德何能?9图对比道出真相
  2. python在线课程-《Python程序设计与应用》在线课程使用说明
  3. 一道抛物线自编题的思考
  4. 第45讲:哪都能存,Item Pipeline 的用法
  5. python拷贝是什么知识点_python闭包、深浅拷贝、垃圾回收、with语句知识点汇总...
  6. android的padding属性,以编程方式获取android:padding属性
  7. 安装默认报表服务器虚拟目录,报表服务器虚拟目录(Reporting Services 配置)
  8. 从Python 2切换到Python 3:您需要了解的内容
  9. Spring Cloud Config服务端配置细节(二)之加密解密
  10. MySQL的FROM_UNIXTIME()和UNIX_TIMESTAMP()函数的区别
  11. linux包含绝对路径头文件,linux-kernel - 访问用户空间内存访问函数(如access_ok(),get_from_user())需要包含的头文件的确切路径。 - 堆栈内存溢出...
  12. 使用微软VS2015编写python代码
  13. css3中插入地图,CSS3 地图展开动画
  14. PHP的.htaccess作用
  15. JavaSocket编程的一个简单例子
  16. HDU 6975 Forgiving Matching 快速傅里叶变换处理带通配符字符串匹配
  17. 学会Python如何利用业余时间赚外快?分享几个接单途径
  18. 腾讯编程比赛的试题,喜欢企鹅和编程的要进!
  19. 【纪中受难记】——Day23:受刑
  20. BW4HANA cockpit 权限设置

热门文章

  1. 解决方法:Linux串口接收字节0x11,0x0d,0x13丢失
  2. 【面试题】七行代码解决酒店老板用瓶子盖子换酒问题
  3. 非常经典有深度的电影英文台词(转)
  4. (转)如何有效使用Project-编制进度计划、保存基准
  5. uni-app 关于自定义标题栏时状态栏高度在不同手机的适配问题
  6. Java线程中的wait、notify和notifyAll解析
  7. 普通人如何不被 OpenAI 取代?
  8. error:bad signature
  9. Ubuntu安装MongoDB4
  10. 世界各个城市和国家经纬度查询-绝对好用