บันทึกการใช้งาน iOS Universal Links และ Android App Links บน React Native

aofleejay
aofleejay
Feb 18 · 3 min read

สำหรับธุรกิจที่มีโปรดักส์ทั้งบนเว็บไซต์และโมบายแอพพลิเคชัน เชื่อว่าหลาย ๆ โปรดักส์ก็อยากจะให้ผู้ที่ใช้งานเว็บไซต์บนมือถือ เปลี่ยนใจเข้ามาใช้งานบนแอพพลิเคชันแทน

ซึ่งหนึ่งวิธีที่น่าสนใจ คือการกดลิงก์แล้วจะเปิดแอพพลิเคชันให้ เมื่อมีแอพพลิเคชันติดตั้งอยู่ในเครื่อง แต่ถ้าหากไม่มี ก็ให้ไปเปิดเว็บไซต์แทน ลองดูตัวอย่างด้านล่างนี้นะครับ

กดที่ลิงก์ แต่แทนที่จะเปิดเว็บไซต์ ก็ให้เปิดแอพพลิเคชันแทน

Universal Links

โจทย์นี้เราสามารถใช้ Universal Links เข้ามาช่วยได้ครับ โดยลักษณะของลิงก์ จะเหมือนกันกับ URL บนเว็บไซต์เลย เช่น https://my-web.com

ความสามารถนี้ ใน iOS เรียกว่า Universal Links ส่วน Android เรียกว่า App Links ในบทความนี้ขอเรียกรวม ๆ ว่า Universal Links แล้วกันนะครับ


ต้องทำอย่างไรบ้าง จึงจะใช้ Universal Links ได้ ?

ทั้ง iOS และ Android มีสองงานที่ต้องทำคือ

  1. ในเว็บไซต์ต้องถือไฟล์เพื่อให้รู้ว่า เว็บไซต์เหล่านี้จะจัดการกับแอพพลิเคชันได้อย่างไรบ้าง
  2. เพิ่มการตั้งค่าในแอพพลิเคชันเกี่ยวกับโดเมนของเว็บไซต์

เรามาดูแต่ละแพลตฟอร์มกัน


iOS

เพิ่มไฟล์ Apple App Site Association (AASA) บนเว็บไซต์

บนเว็บไซต์จะต้องมีไฟล์ Apple App Site Association (AASA) สำหรับบอกว่า เราจะจัดการเว็บไซต์นี้ ให้เปิดแอพพลิเคชันของเราได้อย่างไรบ้าง เช่น เว็บนี้เปิดแอพพลิเคชันตัวไหนได้บ้าง หรือ URL อะไรของเว็บที่สามารถเปิดแอพพลิเคชันของเราได้บ้าง เป็นต้น

ไฟล์นี้จะอยู่ในรูปของ JSON และต้องวางไว้ที่ https://my-web.com/apple-app-site-association หรือ https://my-web.com/.wellknown/apple-app-site-association ก็ได้ โดยจะทำงานบน https เท่านั้นนะ

หน้าตาของไฟล์จะมีเนื้อหาประมาณนี้

{
"applinks": {
"apps": [],
"details": [
{
"appID": "5A67289A19.com.aofleejay.ducker",
"paths": [
"/",
"/about"
]
}
]
}
}
  • details — เป็นอาเรย์ของแอพพลิเคชันที่เกี่ยวข้องกับเว็บไซต์ของเรา สามารถมีได้มากกว่า 1 แอพพลิเคชัน
  • appID — ได้จากการเอา team id (หาได้ใน https://developer.apple.com/account/#/membership) และต่อด้วย bundle id
  • paths — เป็นอาเรย์ที่ระบุว่าส่วนไหนของเว็บไซต์สามารถเปิดหรือไม่สามารถเปิดแอพพลิเคชันของเราได้ สามารถตั้งค่าได้หลายแบบ เช่น "*" คือเข้าได้จากทุก URL ของเว็บไซต์ หรือใส่ "NOT /search" ไว้เพื่อไม่ให้เปิดแอพพลิเคชันได้ เป็นต้น

ตั้งค่า Associated Domain Entitlement ในแอพพลิเคชัน

เราต้องไปตั้งค่าแอพพลิเคชัน โดยการใส่ลิสของโดเมนที่แอพพลิเคชันของเราซัพพอร์ท

ทำได้ผ่าน Xcode โดยเลือก target เป็นแอพพลิเคชันของเรา -> แท็บ Capabilities -> แท็บ Associated Domains -> แล้วเพิ่มโดเมนของเราไป โดยใช้ prefix เป็น applinks: เช่น applinks:my-web.com


Android

เพิ่มไฟล์ Digital Asset Links บนเว็บไซต์

บนเว็บไซต์จะต้องมีไฟล์ JSON ที่เอาไว้จัดการเกี่ยวกับการเปิดแอพพลิเคชัน วางไว้ที่ https://my-web.com/.wellknown/assetlinks.json

สำหรับไฟล์นี้ผมใช้ Android App Links Assistant ใน Android Studio ช่วยสร้างขึ้นมาครับ จะได้หน้าตาประมาณนี้

[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.aofleejay.ducker",
"sha256_cert_fingerprints":
["38:C7:02:86:A6:B0:77:21:3F:11:62:68:FE:24:0D:97:6F:05:6D:9A:4F:37:52:36:D9:22:F1:DE:8B:FE:01:7F"]
}
}
]

เพิ่ม Scheme ในแอพพลิเคชัน

เข้าไปเพิ่ม <intent-filter /> ได้ใน AndroidManifest.xml โดยกำหนด android:scheme และ android:host ตามโดเมนของเราครับ

<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="ducker.netlify.com" />
</intent-filter>

มาลองทดสอบกัน

วิธีทดสอบก็คือวางลิงก์ ให้สามารถคลิกได้ เช่น วางไว้ในโน้ต แล้วลองกดลิงก์ในมือถือดูครับ หากว่ามีแอพก็จะเปิดแอพขึ้นมาทันที แต่ถ้าไม่มีแอพหรือเปิดบนเดสก์ท็อปก็จะเปิดเบราเซอร์ขึ้นมาแทน

หรือถ้าทำใน simulator ก็สามารถใช้คำสั่งดังนี้ได้ครับ

  • iOS — xcrun simctl openurl booted https://my-web.com
  • Android — adb shell am start -W -a android.intent.action.VIEW -d "https://ducker.netlify.com"
เคสนี้มีแอพพลิเคชัน ก็เปิดแอพพลิเคชัน
เคสนี้ไม่มีแอพพลิเคชัน ก็เปิดเว็บไซต์แทน

ตั้งค่าสำหรับ React Native กันต่อ

ใน React Native เราสามารถใช้งาน Universal Links คู่ไปกับ react-navigation ได้ (ดูการติดตั้ง react-navigation ได้ ที่นี่)

สิ่งที่ต้องทำเพิ่มจากปกติคือ ระบุ path ให้กับแต่ละหน้า และตั้งค่า urlPrefix ด้วยโดเมนของเรา เพียงแค่นี้ก็สามารถใช้งาน Universal Links ใน React Native ได้แล้วครับ

จากตัวอย่างด้านล่างเป็น stack navigator ที่มีสองหน้าก็คือหน้า home กับหน้า about ครับ

import React from 'react'
import {
createStackNavigator,
createAppContainer,
} from 'react-navigation'
import { Home, About } from ‘./pages’

เมื่อเรากดลิงก์ด้วย https://my-web.com/about ก็จะเข้าไปยังหน้า about ในแอพพลิเคชันได้เลยครับ


ความแตกต่างระหว่าง Universal Links กับ Deep Links (URI Schemes)

  • หน้าตาของ Deep Links จะไม่ใช่เว็บ URL แต่จะเป็น my-app://home ทำนองนี้แทน ซึ่งก็จะใช้ร่วมกับเว็บไม่ได้
  • Deep Links ไม่รองรับ fallback เช่น ถ้าเราไม่ได้ลงแอพพลิเคชันเอาไว้ หรือไม่มีแอพพลิเคชันตาม Deep Links ที่เรากรอก ก็จะเจอ error ทันที เช่น non-extsting-app:// ต่างกับ Universal Links ที่ถ้าไม่มีแอพพลิเคชัน สามารถไปเปิดเว็บไซต์แทนได้
  • Deep Links สามารถเปิดแอพพลิเคชันของใครก็ได้ เช่น สามารถพิมพ์ fb:// เพื่อเปิดเฟสบุ๊คได้เลย ต่างกับ Universal Links ที่ต้องใช้ Apple App Site Association หรือ Digital Asset Links ไปวางไว้บนเว็บไซต์ของเราก่อน ทำให้มั่นใจได้ว่าจะไม่มีใครมาสั่งเปิดแอพพลิเคชันของเราได้แน่ ๆ

จบไปอีกหนึ่งบทความแล้วนะครับ ขออภัยที่ห่างหายไปนาน สำหรับบทความนี้มีข้อแนะนำหรือติชมอะไรก็สามารถบอกได้เลยนะครับผม ขอให้สนุกกับการโค้ดดิ้งครับ

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade