Info.plist Usage Description — คืออะไร, คีย์ NS*UsageDescription และการตั้งค่า

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-05-21 เวลาอ่าน: 10 นาที

Info.plist Usage Description คือคีย์บังคับในไฟล์ Info.plist ของแอป iOS ที่มีข้อความแสดงแก่ผู้ใช้เมื่อขอเข้าถึงฟังก์ชันระบบ: กล้องถ่ายรูป ไมโครโฟน ตำแหน่งที่ตั้ง อัลบั้มรูปภาพ และอื่นๆ แต่ละคีย์มีคำนำหน้า NS*UsageDescription และให้สตริงที่อธิบายเหตุผลของคำขอเข้าถึง ตาม Apple Information Property List Guide การไม่มีคีย์สำหรับทรัพยากรที่ร้องขอจะทำให้แอปหยุดทำงานทันที

ประเด็นสำคัญ

  • NS*UsageDescription — คีย์ Info.plist พร้อมข้อความเหตุผลการเข้าถึงฟังก์ชันระบบ iOS
  • ความจำเป็น — คำขอเข้าถึงแต่ละครั้งต้องมีคีย์ที่เกี่ยวข้อง มิฉะนั้นแอปจะหยุดทำงาน
  • 14+ คีย์ — กล้องถ่ายรูป ไมโครโฟน ตำแหน่งที่ตั้ง รูปภาพ รายชื่อ ปฏิทิน และอื่นๆ
  • ข้อความ — คำอธิบายต้องเฉพาะเจาะจงและสอดคล้องกับการใช้งานจริง
  • App Store — ผู้ตรวจสอบจะตรวจสอบความสอดคล้องของข้อความกับฟังก์ชันจริง

Info.plist Usage Description คืออะไร?

Info.plist Usage Description คือค่าสตริงของคีย์ที่มีคำนำหน้า NS*UsageDescription ซึ่งกำหนดข้อความของไดอะล็อกระบบเมื่อขอเข้าถึงทรัพยากรที่ได้รับการป้องกันของ iOS เมื่อแอปเรียก API เป็นครั้งแรกที่ต้องการสิทธิ์ผู้ใช้ (เช่น AVCaptureDevice สำหรับกล้อง) iOS จะแสดงไดอะล็อกพร้อมข้อความนี้และปุ่มอนุญาต/ปฏิเสธ

ข้อความคำอธิบายเป็นสิ่งเดียวที่นักพัฒนาสามารถควบคุมได้ในไดอะล็อกระบบ ชื่อไดอะล็อก “<ชื่อแอป> ต้องการเข้าถึง [ทรัพยากร]” ถูกสร้างโดย iOS โดยอัตโนมัติตามประเภทของทรัพยากรที่ร้องขอ นักพัฒนาไม่สามารถเปลี่ยนชื่อ ปุ่ม หรือลักษณะที่ปรากฏ — มีเพียงข้อความอธิบายเท่านั้น

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

Apple แนะนำอย่างยิ่งให้ระบุเหตุผลเฉพาะเจาะจงสำหรับคำขอเข้าถึงในคำอธิบาย ตัวอย่างเช่น “เพื่อถ่ายรูปโปรไฟล์” ดีกว่า “เพื่อเข้าถึงกล้อง” ข้อความเฉพาะเจาะจงช่วยเพิ่มความไว้วางใจของผู้ใช้และอัตราการอนุญาต ตาม Localytics (2023) คำอธิบายที่กำหนดเองช่วยเพิ่มความยินยอม 15-25% เมื่อเทียบกับวลีทั่วไป

ความแตกต่างระหว่าง Usage Description และ ATT

อย่าสับสนระหว่าง NS*UsageDescription กับ ATT (App Tracking Transparency) Usage Description คือคำขอเข้าถึงทรัพยากรระบบ (กล้อง ตำแหน่งที่ตั้ง รูปภาพ) ในขณะที่ ATT คือคำขอติดตาม (เข้าถึง IDFA) ATT ใช้เฟรมเวิร์กแยกต่างหาก AppTrackingTransparency และคีย์ NSUserTrackingUsageDescription ซึ่งไม่ได้เป็นส่วนหนึ่งของ NS*UsageDescription

สิ่งที่เหมือนกันคือทั้งคู่ใช้ไดอะล็อกระบบที่มีข้อความซึ่งแอปไม่สามารถแก้ไขได้ ความแตกต่างคือ Usage Description ทำงานในระดับทรัพยากร ในขณะที่ ATT ทำงานในระดับตัวระบุอุปกรณ์ คีย์ NS*UsageDescription ถูกนำมาใช้ใน iOS 6, ATT — ใน iOS 14.5

วิวัฒนาการของคีย์ในเวอร์ชัน iOS ต่างๆ

ทุกครั้งที่ iOS ปล่อยเวอร์ชันใหม่ Apple จะเพิ่มทรัพยากรที่ได้รับการป้องกันและคีย์ที่เกี่ยวข้อง iOS 6: รายชื่อ ปฏิทิน การเตือนความจำ รูปภาพ iOS 7: ไมโครโฟน iOS 8: HomeKit สุขภาพ iOS 10: คลังสื่อ Siri iOS 11: NFC iOS 14: การติดตาม (ATT) iOS 17: การเข้าถึงคลิปบอร์ด (ต้องการการยืนยันเพิ่มเติม)

สำคัญ: หากแอปใช้ API ที่นำมาใช้ในเวอร์ชัน iOS เฉพาะ แต่เวอร์ชันขั้นต่ำที่รองรับต่ำกว่า คีย์ยังคงจำเป็น iOS ตรวจสอบการมีอยู่ของคีย์ ก่อนการเรียก API ครั้งแรก โดยไม่ขึ้นกับเวอร์ชันที่แอปทำงานบน

คีย์ NS*UsageDescription ที่จำเป็น

รายการคีย์ทั้งหมดขึ้นอยู่กับฟังก์ชันที่แอปใช้ มาดู 14 คีย์หลักที่จำเป็นบ่อยที่สุดในแอปมือถือ

การเข้าถึงสื่อ

คีย์ NSCameraUsageDescription จำเป็นเมื่อเข้าถึงกล้องผ่าน AVCaptureDevice หรือ UIImagePickerController ด้วยแหล่งที่มา .camera คีย์ NSMicrophoneUsageDescription จำเป็นเมื่อบันทึกเสียงผ่าน AVAudioRecorder หรือเมื่อถ่ายวิดีโอพร้อมเสียง ทั้งสองคีย์มักจำเป็นร่วมกันหากแอปบันทึกวิดีโอ

คีย์ NSPhotoLibraryUsageDescription ใช้เมื่ออ่านรูปภาพและวิดีโอจากคลังสื่อของผู้ใช้ผ่าน PHPicker หรือ UIImagePickerController คีย์ NSPhotoLibraryAddUsageDescription ใช้หากแอปบันทึกรูปภาพเท่านั้นแต่อ่านไม่ได้ คีย์แรกขอสิทธิ์อ่าน คีย์ที่สอง — สิทธิ์เขียนเท่านั้น

ตำแหน่งที่ตั้งและการนำทาง

คีย์ NSLocationWhenInUseUsageDescription ให้สิทธิ์เข้าถึงตำแหน่งที่ตั้งเมื่อแอปทำงานอยู่ (บนหน้าจอ) NSLocationAlwaysAndWhenInUseUsageDescription ให้สิทธิ์เข้าถึงตลอดเวลา (รวมถึงโหมดพื้นหลัง) iOS ต้องการทั้งสองคีย์หากต้องการเข้าถึงตลอดเวลา: อันดับแรก WhenInUse จากนั้น Always

คีย์ NSLocationTemporaryUsageDescription และ NSLocationPreciseUsageDescription เป็นคีย์เพิ่มเติมสำหรับขอเข้าถึงชั่วคราวหรือตำแหน่งที่ตั้งที่แม่นยำ ตำแหน่งที่แม่นยำต้องการสิทธิ์แยกต่างหาก และผู้ใช้สามารถเปิดใช้เฉพาะตำแหน่งโดยประมาณเท่านั้น

คีย์ทรัพยากรใช้ได้ตั้งแต่ iOS
NSCameraUsageDescriptionกล้อง6.0
NSMicrophoneUsageDescriptionไมโครโฟน7.0
NSPhotoLibraryUsageDescriptionคลังสื่อ (อ่าน)6.0
NSPhotoLibraryAddUsageDescriptionคลังสื่อ (เขียน)11.0
NFCReaderUsageDescriptionNFC11.0

รายชื่อ ปฏิทิน และข้อมูลอื่นๆ

คีย์ NSContactsUsageDescription ให้สิทธิ์เข้าถึงรายชื่อผู้ใช้ผ่าน CNContactStore NSCalendarsUsageDescription ให้สิทธิ์เข้าถึงปฏิทินเพื่ออ่านและสร้างกิจกรรม NSRemindersUsageDescription ให้สิทธิ์เข้าถึงการเตือนความจำ NSBluetoothAlwaysUsageDescription ให้สิทธิ์เข้าถึง Bluetooth ในพื้นหลัง (เช่น สำหรับอุปกรณ์ BLE)

คีย์ NSHealthShareUsageDescription ให้สิทธิ์อ่านข้อมูล HealthKit NSHealthUpdateUsageDescription ให้สิทธิ์เขียนข้อมูลใน HealthKit ทั้งสองจำเป็นหากแอปทำงานกับข้อมูลสุขภาพ Apple ตรวจสอบแอปที่ใช้ HealthKit อย่างละเอียดและอาจปฏิเสธแอปหากคำอธิบายการใช้งานไม่ตรงกับฟังก์ชัน

วิธีเขียนคำอธิบายอย่างถูกต้อง

ข้อความใน Usage Description ต้องเฉพาะเจาะจง เป็นความจริง และกระชับ Apple ให้คำแนะนำเกี่ยวกับการใช้ภาษา และผู้ตรวจสอบจะตรวจสอบความสอดคล้องกับฟังก์ชัน

โครงสร้างของคำอธิบายที่ดี

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

Apple ห้ามคำอธิบายที่ทำให้เข้าใจผิด หากเขียนว่า “เพื่อถ่ายรูป” แต่แอปยังบันทึกวิดีโอด้วย อาจถือเป็นการหลอกลวง ผู้ตรวจสอบอาจปฏิเสธแอปหรือขอ คำชี้แจง ใน iOS 17 Apple เพิ่มการตรวจสอบอัตโนมัติ: คำอธิบายต้องมีคำสำคัญที่สอดคล้องกับทรัพยากรที่ร้องขอ

การแปลภาษา: คำอธิบายต้องแปลเป็นทุกภาษาที่แอปรองรับ หากแอปมีให้ใช้ใน 10 ภาษา แต่ละคีย์ Usage Description ต้องมีคำแปลในไฟล์ Localizable.strings หรือ InfoPlist.strings Apple แนะนำให้ใช้ InfoPlist.strings สำหรับแปลภาษาคีย์ Info.plist

ตัวอย่างที่ไม่ดีและดี

  • ไม่ดี: “ต้องการเข้าถึงกล้อง” — ไม่ได้อธิบายว่าเหตุใด
  • ดี: “เพื่อสแกนรหัส QR เมื่อชำระเงิน” — เฉพาะเจาะจงและชัดเจน
  • ไม่ดี: “เพื่อระบุตำแหน่งที่ตั้ง” — คลุมเครือ
  • ดี: “เพื่อค้นหาร้านอาหารใกล้เคียงบนแผนที่” — แสดงคุณค่า
  • ไม่ดี: “เพื่อปรับปรุงบริการ” — ไม่มีข้อมูล
  • ดี: “เพื่ออัปโหลดรูปภาพไปยังรีวิวสินค้า” — การกระทำเฉพาะ

การแปลภาษาผ่าน InfoPlist.strings

ในการแปลภาษา Usage Description คุณไม่จำเป็นต้องทำซ้ำ Info.plist สำหรับแต่ละภาษา สร้างไฟล์ InfoPlist.strings ในแต่ละไดเรกทอรีภาษาและระบุค่าคีย์ iOS จะใช้ภาษาที่ถูกต้องโดยอัตโนมัติในไดอะล็อก Xcode รองรับ การแปลภาษาพื้นฐาน สำหรับ Info.plist ตั้งแต่เวอร์ชัน 14

xml
<!-- InfoPlist.strings (Russian) -->
"NSCameraUsageDescription" =
    "เพื่อสแกนรหัส QR";
"NSPhotoLibraryUsageDescription" =
    "เพื่ออัปโหลดรูปภาพไปยังโปรไฟล์";
"NSLocationWhenInUseUsageDescription" =
    "เพื่อแสดงร้านค้าใกล้เคียงบนแผนที่";

การนำไปใช้: โค้ดและการตั้งค่า

การนำ Usage Description ไปใช้อย่างถูกต้องรวมถึงการเพิ่มคีย์ใน Info.plist ตรวจสอบสถานะสิทธิ์ในโค้ด และจัดการกับการปฏิเสธ

การเพิ่มคีย์ผ่าน Xcode

ใน Xcode เปิด Info.plist ชี้ไปที่แถวแล้วคลิก “+” ป้อนชื่อคีย์ (เช่น NSCameraUsageDescription) และระบุสตริงคำอธิบาย Xcode เติมชื่อคีย์ให้อัตโนมัติ ซึ่งลดความเสี่ยงในการพิมพ์ผิด หลังจากเพิ่มแล้ว ให้ สร้างโปรเจกต์ใหม่ และตรวจสอบว่าคีย์ปรากฏในไบนารีสุดท้าย

สำคัญ: คีย์คำนึงถึงตัวพิมพ์ใหญ่-เล็ก NSCameraUsageDescription ถูกต้อง NSCamerausagedescription เป็นข้อผิดพลาด คีย์ที่ไม่ถูกต้องจะถูกละเว้น และแอปจะหยุดทำงานเมื่อเรียก API ใช้การคัดลอกจากเอกสาร Apple หรือการเติมข้อความอัตโนมัติของ Xcode เพื่อหลีกเลี่ยงการพิมพ์ผิด

swift
import AVFoundation
import Photos

final class PermissionManager {
    static func checkCameraPermission() {
        let status = AVCaptureDevice.authorizationStatus(for: .video)
        switch status {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { granted in
                print("Camera access: \(granted)")
            }
        case .denied:
            print("Camera access denied")
        case .authorized:
            print("Camera access authorized")
        @unknown default:
            break
        }
    }

    static func requestPhotoLibraryAccess() {
        PHPhotoLibrary.requestAuthorization { status in
            print("Photo library status: \(status.rawValue)")
        }
    }
}

การจัดการกับการปฏิเสธการเข้าถึง

หากผู้ใช้ปฏิเสธการเข้าถึง แอปไม่ควรเรียกไดอะล็อกระบบอีก — เป็นไปไม่ได้ ให้แสดงหน้าจอข้อมูลที่อธิบายวิธีเปิดใช้งานการเข้าถึงผ่านการตั้งค่า พร้อมปุ่ม “เปิดการตั้งค่า” (UIApplicationOpenSettingsURLString) แนวทางนี้ช่วยปรับปรุง ประสบการณ์ผู้ใช้ และโอกาสที่ผู้ใช้จะเปิดใช้งานการเข้าถึง

อย่าแสดงการแจ้งเตือนขอให้เปิดใช้งานการเข้าถึงทันทีหลังจากการปฏิเสธ — ให้เวลาผู้ใช้ทำความเข้าใจว่าทำไมพวกเขาอาจต้องใช้ฟังก์ชันนี้ ควรแสดงคำอธิบายเมื่อพยายามใช้ฟังก์ชันที่ต้องใช้สิทธิ์นี้ UX Movement (2023) แนะนำให้แสดงหน้าจอคำอธิบายหลังจาก 2-3 เซสชันหลังการปฏิเสธ

swift
func showSettingsAlert(for feature: String) {
    let alert = UIAlertController(
        title: "การเข้าถึง \(feature)",
        message: "Allow access in Settings, "
            + "to use this feature",
        preferredStyle: .alert
    )
    alert.addAction(UIAlertAction(
        title: "Open Settings",
        style: .default
    ) { _ in
        if let url = URL(string: UIApplication.openSettingsURLString) {
            UIApplication.shared.open(url)
        }
    })
    alert.addAction(UIAlertAction(
        title: "Not now", style: .cancel
    ))
    UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)
}

จะเกิดอะไรขึ้นหากไม่ระบุ Usage Description

การไม่มีคีย์ Usage Description ที่จำเป็นทำให้แอปหยุดทำงานทันทีเมื่อเรียก API ที่เกี่ยวข้องครั้งแรก นี่ไม่ใช่คำเตือนของ Xcode แต่เป็น การหยุดทำงานขณะรันไทม์ ด้วย NSInvalidArgumentException และข้อความในคอนโซล: “แอปนี้หยุดทำงานเนื่องจากพยายามเข้าถึงข้อมูลที่ละเอียดอ่อนเกี่ยวกับความเป็นส่วนตัวโดยไม่มีคำอธิบายการใช้งาน”

พฤติกรรมขณะรันไทม์โดยไม่มีคีย์

iOS ตรวจสอบการมีอยู่ของคีย์ NS*UsageDescription ใน Info.plist เมื่อเรียก API ครั้งแรกสำหรับทรัพยากรที่ได้รับการป้องกัน หากคีย์หายไป ระบบปฏิบัติการจะยุติแอปทันทีด้วย สัญญาณ SIGABRT สิ่งนี้เกิดขึ้นแม้ในอุปกรณ์ดีบัก — Xcode แสดงข้อยกเว้นในบันทึก แต่ดีบักเกอร์ไม่จับเป็นจุดหยุด

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

สถานการณ์พิเศษกับ iOS 17+: Apple เพิ่มการตรวจสอบเพิ่มเติมสำหรับการเข้าถึงคลิปบอร์ด (UIPasteboard) หากแอปอ่านคลิปบอร์ดโดยไม่มีการกระทำที่ชัดเจนของผู้ใช้ iOS จะแสดงแบนเนอร์เตือน แม้ว่าคีย์ Usage Description จะมีอยู่ก็ตาม คลิปบอร์ดไม่ต้องการคีย์แยกต่างหาก แต่ Apple แนะนำให้ ลด การอ่านอัตโนมัติ

ข้อผิดพลาดในการตรวจสอบ App Store

นอกจากการหยุดทำงานขณะรันไทม์ การไม่มีคีย์อาจทำให้แอปถูกปฏิเสธระหว่างการตรวจสอบ Apple ตรวจสอบ Info.plist ในขั้นตอนการตรวจสอบและอาจปฏิเสธบิลด์หากตรวจพบการเรียก API โดยไม่มีคีย์ที่เกี่ยวข้อง Xcode ไม่บล็อกการเก็บถาวร แต่ App Store Connect อาจส่งคืนข้อผิดพลาดเมื่อประมวลผลไบนารี

หากแอปไม่ได้ใช้ทรัพยากรโดยตรง แต่ SDK ของบุคคลที่สามทำ (เช่น SDK วิเคราะห์ขอ IDFA) นักพัฒนายังคงต้องเพิ่มคีย์ที่เกี่ยวข้อง Apple ตรวจสอบ การเรียก API ทั้งหมด ในไบนารี รวมถึงโค้ดจากไลบรารีแบบสแตติกและไดนามิก ข้อผิดพลาด “คีย์ Info.plist หายไป” เป็นหนึ่งในสาเหตุที่พบบ่อยที่สุดของการปฏิเสธการอัปเดต

คำถามที่พบบ่อย

จำเป็นต้องมีคีย์หรือไม่หากแอปไม่ได้ใช้ API โดยตรง?

ใช่ หาก SDK ของบุคคลที่สามเรียก API การเข้าถึงทรัพยากร (กล้อง ตำแหน่งที่ตั้ง รูปภาพ) คีย์เป็นสิ่ง จำเป็น iOS ตรวจสอบไบนารีทั้งหมด รวมถึงการพึ่งพา และหยุดแอปหากคีย์หายไป

สามารถใช้คีย์เดียวสำหรับหลาย API ได้หรือไม่?

ไม่ แต่ละทรัพยากรที่ได้รับการป้องกันต้องการคีย์แยกต่างหาก ตัวอย่างเช่น NSCameraUsageDescription ไม่สามารถแทนที่ NSMicrophoneUsageDescription ระบบค้นหาคีย์ เฉพาะ ตามชื่อเมื่อเรียกแต่ละ API

จะทำอย่างไรหากผู้ใช้ปฏิเสธการเข้าถึง?

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

วิธีแปลภาษา Usage Description?

สร้างไฟล์ InfoPlist.strings สำหรับแต่ละภาษาและระบุคำแปล iOS ใช้ภาษาของอุปกรณ์โดยอัตโนมัติเมื่อแสดงไดอะล็อก Xcode ยังรองรับ การแปลภาษาพื้นฐาน สำหรับ Info.plist

ทำไมแอปถึงหยุดทำงานโดยไม่มีคีย์บนซิมิวเลเตอร์?

ซิมิวเลเตอร์ iOS จำลองพฤติกรรมของอุปกรณ์อย่างสมบูรณ์ รวมถึงการตรวจสอบ Usage Description หากคีย์หายไป ซิมิวเลเตอร์ จะยุติแอปด้วยข้อยกเว้นเช่นกัน นี่เป็นพฤติกรรมการดีบักที่คาดหวัง

สรุป

  • NS*UsageDescription — คีย์ Info.plist ที่จำเป็นสำหรับการเข้าถึงกล้อง ตำแหน่งที่ตั้ง รายชื่อ และทรัพยากรอื่นๆ
  • การหยุดทำงานขณะรันไทม์ — คีย์ที่หายไปทำให้แอปยุติทันทีเมื่อเรียก API
  • 14+ คีย์ — แต่ละทรัพยากรที่ได้รับการป้องกันต้องการคีย์แยกต่างหากพร้อมชื่อที่ไม่ซ้ำกัน
  • การแปลภาษา — ใช้ InfoPlist.strings เพื่อแปลคำอธิบายเป็นทุกภาษาของแอป
  • ความเฉพาะเจาะจง — ข้อความควรอธิบายเหตุผลที่แน่ชัดในการเข้าถึง ไม่ใช่วัตถุประสงค์ทั่วไป
  • SDK — คำนึงถึง API ที่เรียกโดย SDK ของบุคคลที่สามและเพิ่มคีย์สำหรับ API เหล่านั้น
  • ตรวจสอบคีย์ทั้งหมดก่อนเก็บถาวรและทดสอบบนซิมิวเลเตอร์ด้วยสถานการณ์การเข้าถึงต่างๆ

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม