Permissions: การขอสิทธิ์การเข้าถึงต่างๆ ใน React Native
สวัสดีครับนักพัฒนา React Native ทุกท่าน! จากบทที่แล้วที่เราได้เรียนรู้การใช้งานแผนที่ในแอปพลิเคชันของเรา วันนี้เราจะมาพูดถึงเรื่องที่สำคัญไม่แพ้กัน นั่นก็คือเรื่องของ Permissions หรือการขอสิทธิ์การเข้าถึงทรัพยากรต่างๆ ของอุปกรณ์จากผู้ใช้งาน
แอปพลิเคชันมือถือสมัยใหม่ มักจะต้องการเข้าถึงข้อมูลหรือฟังก์ชันการทำงานต่างๆ ของอุปกรณ์ เช่น กล้องถ่ายรูป, ตำแหน่งที่ตั้ง (Location), ไมโครโฟน, รายชื่อผู้ติดต่อ, หรือแม้แต่พื้นที่จัดเก็บข้อมูล (Storage) ซึ่งการเข้าถึงข้อมูลเหล่านี้ จำเป็นต้องได้รับการอนุญาตจากผู้ใช้งานก่อนเสมอ เพื่อความเป็นส่วนตัวและความปลอดภัยของผู้ใช้งานเอง
ในบทความนี้ เราจะมาเรียนรู้วิธีการขอ Permissions ต่างๆ ใน React Native อย่างถูกต้องและมีประสิทธิภาพ รวมถึงการจัดการกับสถานการณ์ที่ผู้ใช้ปฏิเสธการให้สิทธิ์ เพื่อให้แอปพลิเคชันของเราสามารถทำงานได้อย่างราบรื่นและเป็นมิตรกับผู้ใช้งาน
ทำไมต้องขอ Permissions?
ก่อนที่เราจะลงมือเขียนโค้ด เรามาทำความเข้าใจกันก่อนว่าทำไมการขอ Permissions ถึงมีความสำคัญ และทำไมเราถึงต้องใส่ใจกับเรื่องนี้เป็นพิเศษ
- ความเป็นส่วนตัวของผู้ใช้งาน: ผู้ใช้งานมีสิทธิ์ที่จะควบคุมว่าแอปพลิเคชันใดสามารถเข้าถึงข้อมูลส่วนตัวของพวกเขาได้บ้าง การขอ Permissions อย่างถูกต้อง ช่วยให้ผู้ใช้งานรู้สึกมั่นใจและปลอดภัยในการใช้งานแอปพลิเคชันของเรา
- ข้อกำหนดของระบบปฏิบัติการ: ทั้ง iOS และ Android มีระบบ Permissions ที่เข้มงวด หากแอปพลิเคชันพยายามเข้าถึงทรัพยากรที่ต้องการสิทธิ์ โดยที่ยังไม่ได้รับการอนุญาต ระบบปฏิบัติการจะทำการบล็อกการเข้าถึงนั้น และอาจทำให้แอปพลิเคชันเกิดข้อผิดพลาดหรือทำงานผิดปกติ
- ประสบการณ์การใช้งานที่ดี: การขอ Permissions ที่ไม่จำเป็น หรือการขอ Permissions ในเวลาที่ไม่เหมาะสม อาจทำให้ผู้ใช้งานรู้สึกรำคาญและไม่พอใจ การขอ Permissions เฉพาะเมื่อจำเป็น และอธิบายเหตุผลในการขออย่างชัดเจน จะช่วยให้ผู้ใช้งานเข้าใจและยินดีให้สิทธิ์มากขึ้น
การติดตั้ง Permissions Library
React Native ไม่ได้มี API สำหรับการจัดการ Permissions ติดตั้งมาให้ในตัว ดังนั้นเราจึงจำเป็นต้องใช้ Library ภายนอกเพื่อช่วยในการจัดการ Permissions ที่นิยมใช้กันคือ `react-native-permissions` ซึ่งรองรับทั้ง iOS และ Android
ในการติดตั้ง `react-native-permissions` ให้เปิด Terminal แล้วรันคำสั่ง:
npm install react-native-permissions
# หรือ
yarn add react-native-permissions
หลังจากติดตั้ง Library แล้ว ให้ทำการ Link Library เข้ากับ Project ของเรา (สำหรับ React Native เวอร์ชั่นเก่ากว่า 0.60)
react-native link react-native-permissions
สำหรับ iOS ให้ทำการ Install Pods:
cd ios
pod install
cd ..
ข้อควรระวัง: อย่าลืม Restart Metro Bundler หลังจากติดตั้ง Library ใหม่เสมอ เพื่อให้ React Native สามารถค้นหา Library ได้
การกำหนด Permissions ในไฟล์ Configuration
ก่อนที่เราจะเริ่มเขียนโค้ดเพื่อขอ Permissions เราต้องทำการกำหนด Permissions ที่เราต้องการในไฟล์ Configuration ของแต่ละ Platform ก่อน
Android
เปิดไฟล์ `android/app/src/main/AndroidManifest.xml` แล้วเพิ่ม Permissions ที่ต้องการภายใน Tag `` เช่น ถ้าเราต้องการขอสิทธิ์ในการเข้าถึงกล้องถ่ายรูป เราจะต้องเพิ่ม Permission ดังนี้:
<uses-permission android:name="android.permission.CAMERA" />
Permissions อื่นๆ ที่พบบ่อย:
- `android.permission.ACCESS_FINE_LOCATION`: สิทธิ์ในการเข้าถึงตำแหน่งที่ตั้งแบบละเอียด (ใช้ GPS)
- `android.permission.ACCESS_COARSE_LOCATION`: สิทธิ์ในการเข้าถึงตำแหน่งที่ตั้งแบบหยาบ (ใช้ Wi-Fi หรือ Cell Tower)
- `android.permission.READ_CONTACTS`: สิทธิ์ในการอ่านรายชื่อผู้ติดต่อ
- `android.permission.WRITE_EXTERNAL_STORAGE`: สิทธิ์ในการเขียนข้อมูลลงใน Storage
- `android.permission.READ_EXTERNAL_STORAGE`: สิทธิ์ในการอ่านข้อมูลจาก Storage
iOS
เปิดไฟล์ `ios/YourProjectName/Info.plist` แล้วเพิ่ม Keys ที่เกี่ยวข้องกับ Permissions ที่ต้องการ เช่น ถ้าเราต้องการขอสิทธิ์ในการเข้าถึงกล้องถ่ายรูป เราจะต้องเพิ่ม Key `NSCameraUsageDescription` พร้อมกับข้อความอธิบายเหตุผลในการขอสิทธิ์:
<key>NSCameraUsageDescription</key>
<string>แอปนี้ต้องการเข้าถึงกล้องถ่ายรูปเพื่อถ่ายภาพ</string>
Keys อื่นๆ ที่พบบ่อย:
- `NSLocationWhenInUseUsageDescription`: คำอธิบายเหตุผลในการขอสิทธิ์เข้าถึงตำแหน่งที่ตั้งขณะใช้งานแอป
- `NSLocationAlwaysUsageDescription`: คำอธิบายเหตุผลในการขอสิทธิ์เข้าถึงตำแหน่งที่ตั้งตลอดเวลา (Background Location) (ข้อควรระวัง: การขอสิทธิ์นี้ต้องมีเหตุผลที่สมเหตุสมผล มิฉะนั้น Apple อาจไม่อนุมัติแอปของคุณ)
- `NSContactsUsageDescription`: คำอธิบายเหตุผลในการขอสิทธิ์เข้าถึงรายชื่อผู้ติดต่อ
- `NSPhotoLibraryUsageDescription`: คำอธิบายเหตุผลในการขอสิทธิ์เข้าถึงคลังรูปภาพ
- `NSMicrophoneUsageDescription`: คำอธิบายเหตุผลในการขอสิทธิ์เข้าถึงไมโครโฟน
สำคัญ: ข้อความอธิบายเหตุผลในการขอสิทธิ์ (`Usage Description`) เป็นสิ่งที่สำคัญมาก ผู้ใช้งานจะเห็นข้อความนี้เมื่อระบบขอ Permissions ดังนั้นควรเขียนข้อความที่ชัดเจน เข้าใจง่าย และอธิบายเหตุผลในการขอสิทธิ์อย่างตรงไปตรงมา
การขอ Permission ด้วย `react-native-permissions`
เมื่อเราทำการติดตั้ง Library และกำหนด Permissions ในไฟล์ Configuration เรียบร้อยแล้ว เราก็พร้อมที่จะเริ่มเขียนโค้ดเพื่อขอ Permissions จากผู้ใช้งาน
ตัวอย่างการขอ Permission เข้าถึงกล้องถ่ายรูป:
import { PermissionsAndroid, Platform } from 'react-native';
import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions';
const requestCameraPermission = async () => {
try {
let permissionStatus;
if (Platform.OS === 'android') {
permissionStatus = await check(PERMISSIONS.ANDROID.CAMERA); // ตรวจสอบสถานะ Permission ก่อน
if (permissionStatus === RESULTS.GRANTED) {
console.log("Camera permission already granted");
return true;
}
const granted = await request(PERMISSIONS.ANDROID.CAMERA); // ขอ Permission
if (granted === RESULTS.GRANTED) {
console.log("You can use the camera");
return true;
} else {
console.log("Camera permission denied");
return false;
}
} else if (Platform.OS === 'ios') {
permissionStatus = await check(PERMISSIONS.IOS.CAMERA);
if (permissionStatus === RESULTS.GRANTED) {
console.log("Camera permission already granted");
return true;
}
const granted = await request(PERMISSIONS.IOS.CAMERA);
if (granted === RESULTS.GRANTED) {
console.log("You can use the camera");
return true;
} else {
console.log("Camera permission denied");
return false;
}
} else {
console.log("Unsupported platform");
return false;
}
} catch (err) {
console.warn(err);
return false;
}
};
// เรียกใช้งาน Function
requestCameraPermission();
อธิบายโค้ด:
- เรา Import `PermissionsAndroid` และ `Platform` จาก `react-native` เพื่อตรวจสอบ Platform ที่แอปพลิเคชันกำลังทำงานอยู่ และ Import `check`, `request`, `PERMISSIONS`, และ `RESULTS` จาก `react-native-permissions`
- เราสร้าง Function `requestCameraPermission` เพื่อขอ Permission เข้าถึงกล้องถ่ายรูป
- เราใช้ `Platform.OS` เพื่อตรวจสอบว่าแอปพลิเคชันกำลังทำงานอยู่บน Android หรือ iOS
- เราใช้ `check` เพื่อตรวจสอบสถานะของ Permission ก่อนที่จะทำการขอ Permission หาก Permission ได้รับการอนุญาตแล้ว เราก็ไม่จำเป็นต้องขอ Permission อีก
- เราใช้ `request` เพื่อขอ Permission จากผู้ใช้งาน
- เราตรวจสอบผลลัพธ์ของการขอ Permission หากผู้ใช้งานอนุญาต เราจะ Return `true` หากผู้ใช้งานปฏิเสธ เราจะ Return `false`
- เรา Handle Errors ที่อาจเกิดขึ้นระหว่างการขอ Permission
ข้อควรจำ: ค่า `PERMISSIONS.ANDROID.CAMERA` และ `PERMISSIONS.IOS.CAMERA` เป็นค่าคงที่ (Constant) ที่กำหนดไว้ใน `react-native-permissions` ซึ่งจะแตกต่างกันไปตาม Platform และ Permission ที่ต้องการ
การจัดการกรณีที่ผู้ใช้ปฏิเสธ Permission
สิ่งที่ต้องพิจารณาคือ ผู้ใช้งานอาจปฏิเสธการให้สิทธิ์แก่แอปพลิเคชันของเราได้ ดังนั้นเราจึงต้องเตรียมพร้อมรับมือกับสถานการณ์นี้
แนวทางในการจัดการกรณีที่ผู้ใช้ปฏิเสธ Permission:
- อธิบายเหตุผลอีกครั้ง: แสดงข้อความอธิบายเหตุผลในการขอสิทธิ์อีกครั้งอย่างละเอียด และเน้นย้ำถึงประโยชน์ที่ผู้ใช้งานจะได้รับจากการให้สิทธิ์
- นำทางไปยัง Settings: หากผู้ใช้งานปฏิเสธ Permission อย่างถาวร (Don't ask again) เราสามารถนำทางผู้ใช้งานไปยังหน้า Settings ของแอปพลิเคชัน เพื่อให้ผู้ใช้งานสามารถเปิด Permission ได้เอง
- ลดทอน Functionality: หากแอปพลิเคชันไม่สามารถทำงานได้ตามปกติหากไม่มี Permission ที่จำเป็น เราอาจต้องลดทอน Functionality ของแอปพลิเคชันลง หรือแสดงข้อความแจ้งเตือนให้ผู้ใช้งานทราบ
ตัวอย่างการนำทางไปยัง Settings (Android):
import { Linking } from 'react-native';
const openSettings = () => {
Linking.openSettings().catch(console.log);
};
ข้อควรระวัง: การขอ Permission ซ้ำๆ หลังจากที่ผู้ใช้งานปฏิเสธไปแล้ว อาจทำให้ผู้ใช้งานรู้สึกรำคาญและลบแอปพลิเคชันของเราได้ ดังนั้นควรขอ Permission เฉพาะเมื่อจำเป็น และอธิบายเหตุผลในการขออย่างชัดเจน
แนวปฏิบัติที่ดีในการจัดการ Permissions
เพื่อให้การจัดการ Permissions ในแอปพลิเคชัน React Native ของเรามีประสิทธิภาพและเป็นมิตรกับผู้ใช้งาน เราควรปฏิบัติตามแนวทางดังนี้:
- ขอ Permission เฉพาะเมื่อจำเป็น: อย่าขอ Permission ก่อนที่ผู้ใช้งานจะต้องการใช้งาน Function ที่ต้องใช้ Permission นั้น
- อธิบายเหตุผลในการขอ Permission อย่างชัดเจน: ผู้ใช้งานควรเข้าใจว่าทำไมเราถึงต้องการ Permission นั้น และพวกเขาจะได้รับประโยชน์อะไรจากการให้สิทธิ์
- Handle Error Cases อย่างเหมาะสม: เตรียมพร้อมรับมือกับสถานการณ์ที่ผู้ใช้งานปฏิเสธ Permission หรือเกิดข้อผิดพลาดระหว่างการขอ Permission
- ทดสอบบนอุปกรณ์จริง: การทดสอบบน Simulator หรือ Emulator อาจไม่เหมือนกับการทดสอบบนอุปกรณ์จริง ดังนั้นควรทดสอบการขอ Permissions บนอุปกรณ์จริงด้วย
- ติดตาม Best Practices: ติดตามข่าวสารและ Best Practices เกี่ยวกับการจัดการ Permissions จาก Apple และ Google อยู่เสมอ
หวังว่าบทความนี้จะเป็นประโยชน์ในการจัดการ Permissions ในแอปพลิเคชัน React Native ของคุณนะครับ ในบทความหน้า เราจะมาเรียนรู้เกี่ยวกับการ Deploy แอป React Native ขึ้น Store กันครับ แล้วพบกันใหม่!