यूआरआई से मेल खाने वाले डीप लिंक

हायरारकी वाले यूआरआई को पैटर्न से मैच करने और आर्ग्युमेंट निकालने के लिए, UriDeepLinkMatcher का इस्तेमाल करें. यह kotlinx.serialization पर निर्भर करता है, ताकि मैच होने वाले आर्ग्युमेंट को आपकी मुख्य क्लास में डीसीरियलाइज़ किया जा सके.

UriDeepLinkMatcher बनाने के लिए, पैटर्न DeepLinkUri और उससे जुड़ी कुंजी के लिए सीरियलाइज़र दें:

नॉन-हैरारकी वाले यूआरआई या कस्टम स्कीम (जैसे कि tel:) के लिए, कस्टम डीप लिंक मैचर बनाएं देखें.

मैच करने वाले ऐसे पैटर्न जो इस्तेमाल किए जा सकते हैं

UriDeepLinkMatcher, यूआरआई को उनके पांच कॉम्पोनेंट के आधार पर मैच करता है: स्कीम, अथॉरिटी, पाथ, क्वेरी, और फ़्रैगमेंट. यहां दिए गए सेक्शन में, हर कॉम्पोनेंट के लिए इस्तेमाल किए जा सकने वाले पैटर्न सिंटैक्स, आर्ग्युमेंट प्लेसहोल्डर, और मैच करने के नियमों के बारे में बताया गया है.

स्कीम मैचिंग

अगर यूआरआई पैटर्न में कोई स्कीम मौजूद नहीं है, तो http और https, दोनों मैच किए जाते हैं. किसी खास स्कीम से मैच करने के लिए, उसे पैटर्न में शामिल करें. अपवाद के तौर पर, किसी पैटर्न में http स्कीम, http और https, दोनों अनुरोध यूआरआई से मैच करती है. हालांकि, किसी पैटर्न में https सिर्फ़ https अनुरोधों से मैच करता है.

पैटर्न यूआरआई अनुरोध यूआरआई मिलते-जुलते वीडियो
www.example.com https://www.example.com ✅
www.example.com http://www.example.com ✅
http://www.example.com http://www.example.com ✅
http://www.example.com https://www.example.com ✅
https://www.example.com http://www.example.com ❌
myapp://www.example.com myapp://www.example.com ✅

अथॉरिटी मैचिंग

UriDeepLinkMatcher, यूआरआई अथॉरिटी (होस्ट और वैकल्पिक पोर्ट) पर केस-इनसेंसिटिव एग्ज़ैक्ट मैच करता है. अथॉरिटी में प्लेसहोल्डर या वाइल्डकार्ड का इस्तेमाल नहीं किया जा सकता. साथ ही, कोई आर्ग्युमेंट नहीं निकाला जाता:

पैटर्न यूआरआई अनुरोध यूआरआई मिलते-जुलते वीडियो
example.com https://example.com ✅
example.com https://EXAMPLE.COM ✅
example.com https://sub.example.com ❌
example.com https://www.example.com ❌
example.com https://example.com:8080 ❌
example.com:8080 https://example.com:8080 ✅
example.com:8080 https://example.com ❌

पाथ मैचिंग

ये पाथ पैटर्न इस्तेमाल किए जा सकते हैं:

पैटर्न यूआरआई अनुरोध यूआरआई मिलते-जुलते वीडियो एक्सट्रैक्ट किए गए आर्ग्युमेंट
www.example.com/users https://www.example.com/users ✅ कोई नहीं
www.example.com/users/{id} https://www.example.com/users/123 ✅ id: "123"
www.example.com/users/{first}-{last} https://www.example.com/users/john-doe ✅ first: "john", last: "doe"
www.example.com/users/{id}/profile https://www.example.com/users//profile ✅ id: "" (खाली स्ट्रिंग)
www.example.com/users/user_{id} https://www.example.com/users/user_123 ✅ id: "123"
www.example.com/users/{userId}/posts/{postId} https://www.example.com/users/123/posts/456 ✅ userId: "123", postId: "456"
www.example.com/users/.* https://www.example.com/users/john-doe ✅ कोई नहीं
www.example.com/users https://www.example.com/users/ ❌ (ट्रेलिंग स्लैश से एक अतिरिक्त सेगमेंट बनता है) लागू नहीं

क्वेरी मैचिंग

अनुरोध यूआरआई में क्वेरी पैरामीटर का क्रम, पैटर्न यूआरआई में दिए गए क्रम से मेल खाना ज़रूरी नहीं है. इसके अलावा, अनुरोध यूआरआई में मौजूद उन पैरामीटर को अनदेखा कर दिया जाता है जो पैटर्न यूआरआई में मौजूद नहीं होते.

क्वेरी पैरामीटर के ये पैटर्न इस्तेमाल किए जा सकते हैं:

पैटर्न यूआरआई अनुरोध यूआरआई एक्सट्रैक्ट किए गए आर्ग्युमेंट
www.example.com/users?name={name} https://www.example.com/users?name=john name: "john"
www.example.com/users?name={name} https://www.example.com/users?name= name: "" (खाली स्ट्रिंग)
www.example.com/users?{rawQuery} https://www.example.com/users?anything&else rawQuery: ["anything", "else"]
www.example.com/users?type=user_{id} https://www.example.com/users?type=user_123 id: "123"
www.example.com/users?name={first}_{last} https://www.example.com/users?name=john_doe first: "john", last: "doe"
www.example.com/users?list={list} https://www.example.com/users?list=10&list=20 list: ["10", "20"]
www.example.com/users?name={name}&{other} https://www.example.com/users?name=john&tab=info name: "john", other: ["tab=info"]
www.example.com/users?type=user_.* https://www.example.com/users?type=user_admin type: "admin"

फ़्रैगमेंट मैचिंग

फ़्रैगमेंट पैटर्न के ये टाइप इस्तेमाल किए जा सकते हैं:

पैटर्न यूआरआई अनुरोध यूआरआई एक्सट्रैक्ट किए गए आर्ग्युमेंट
www.example.com/#section1 https://www.example.com/#section1 कोई नहीं
www.example.com/#section_{id} https://www.example.com/#section_123 id: "123"
www.example.com/#section_.* https://www.example.com/#section_123 कोई नहीं

किस तरह के डेटा को ट्रांसफ़र किया जा सकता है

UriDeepLinkMatcher, यूआरआई आर्ग्युमेंट को प्रिमिटिव टाइप, enum, कलेक्शन, और कस्टम ऑब्जेक्ट में डीसीरियलाइज़ करने की सुविधा देता है. सीरियलाइज़ेशन को दो कैटगरी में बांटा जा सकता है:

  • स्टैंडर्ड सीरियलाइज़ेशन: इसमें kotlinx.serialization का इस्तेमाल करके, डेटा को डीसीरियलाइज़ किया जाता है:
    • प्रिमिटिव (Boolean, Int, Long, Float, Double, Char, Byte, Short) और String
    • एनम्स
    • Set, List या Array प्रिमिटिव, स्ट्रिंग या एनम
    • नेस्टेड @Serializable क्लास (इनकी प्रॉपर्टी को अलग-अलग यूआरआई प्लेसहोल्डर में फ़्लैट किया जाता है)
  • DeepLinkSerializer के साथ कस्टम सीरियलाइज़ेशन: यह एक String और कस्टम ऑब्जेक्ट, बाहरी टाइप (जैसे कि java.time.LocalDate) या कस्टम-डिलिमिटेड कलेक्शन के बीच कन्वर्ज़न करता है.

स्टैंडर्ड सीरियलाइज़ेशन

UriDeepLinkMatcher, स्टैंडर्ड टाइप और फ़्लैट किए गए स्ट्रक्चर के लिए, कस्टम सीरियलाइज़र को लागू किए बिना ही काम करता है.

प्रिमिटिव और स्ट्रिंग

UriDeepLinkMatcher, प्रिमिटिव टाइप (Boolean, Int, Long, Float, Double, Char, Byte, Short) और String को अपने-आप डिकोड करता है:

एनम्स

ईनम की वैल्यू, ईनम एलिमेंट के नामों से केस-सेंसिटिव तरीके से मैच की जाती हैं:

बार-बार पूछे जाने वाले सवालों के कलेक्शन

बार-बार इस्तेमाल होने वाली कुंजियों (जैसे, ?id=10&id=20) वाले क्वेरी पैरामीटर, अपने-आप List<T>, Set<T> या Array<T> में डीसीरियलाइज़ हो जाते हैं. यहां T एक प्रिमिटिव टाइप, String या enum है:

नेस्ट की गई @Serializable क्लास

जब किसी NavKey में ऐसी प्रॉपर्टी शामिल होती है जिसका टाइप कोई दूसरा @Serializable क्लास होता है, तो UriDeepLinkMatcher इसकी प्रॉपर्टी को फ़्लैट कर देता है. इससे नेस्ट की गई क्लास की हर प्रॉपर्टी, सीधे तौर पर उसी नाम के अलग-अलग यूआरआई पैरामीटर से मैप हो जाती है:

कस्टम ऑब्जेक्ट (जैसे, Filter(key = "brand", value = "pixel")), बाहरी टाइप (जैसे, java.time.LocalDate) या कस्टम डीलिमिटेड स्ट्रिंग (जैसे, कॉमा लगाकर अलग की गई वैल्यू) को डीसीरियलाइज़ करने के लिए, DeepLinkSerializer<T> को बढ़ाएं.

DeepLinkSerializer<T> एक ऐब्स्ट्रैक्ट KSerializer<T> है, जो String और T के बीच कन्वर्ज़न करता है:

abstract class DeepLinkSerializer<T : Any> : KSerializer<T> {
    abstract val serialName: String
    abstract fun deserialize(value: String): T
    abstract fun serialize(value: T): String
}

उदाहरण के लिए, Filter और FilterSerializer की परिभाषाओं पर ध्यान दें, जिनका इस्तेमाल इन स्निपेट में किया गया है:

सिंगल कस्टम ऑब्जेक्ट

किसी ऑब्जेक्ट को एक यूआरआई पैरामीटर स्ट्रिंग (जैसे कि ?filter=brand:google) से डिकोड करने के लिए, प्रॉपर्टी को @Serializable(with = ...) के साथ एनोटेट करें:

बार-बार इस्तेमाल होने वाले क्वेरी पैरामीटर में कस्टम ऑब्जेक्ट

बार-बार इस्तेमाल होने वाले क्वेरी पैरामीटर को कस्टम ऑब्जेक्ट (List<T>, Set<T> या Array<T>) के कलेक्शन में डीसीरियलाइज़ करने के लिए, एलिमेंट टाइप T के लिए DeepLinkSerializer<T> लागू करें. साथ ही, प्रॉपर्टी के टाइप आर्ग्युमेंट को @Serializable(with = ...) के साथ एनोटेट करें:

सिंगल पैरामीटर में डीलिमिटेड कलेक्शन

कॉमा लगाकर अलग किए गए या कस्टम-डीलिमिटेड वैल्यू (जैसे कि ?ids=1,2,3) को किसी कलेक्शन में पार्स करने के लिए, पूरे कलेक्शन टाइप के लिए DeepLinkSerializer लागू करें और प्रॉपर्टी को @Serializable(with = ...) के साथ एनोटेट करें:

तर्कों की पुष्टि करना और नतीजों का मिलान करना

UriDeepLinkMatcher, मेल न खाने वाली वैल्यू (null दिखाता है, ताकि अन्य मैचर को आज़माया जा सके) और काम न करने वाले कॉन्फ़िगरेशन (अपवाद दिखाता है) के बीच अंतर करता है.

मेल न खाने वाली वैल्यू

मिसमैच तब होता है, जब कोई इनकमिंग अनुरोध URI, पैटर्न या टाइप की ज़रूरी शर्तों को पूरा नहीं करता:

  • ज़रूरी पैरामीटर मौजूद नहीं हैं: ऐसी मुख्य प्रॉपर्टी जिनकी वैल्यू शून्य नहीं हो सकती और जिनकी डिफ़ॉल्ट वैल्यू नहीं होती. साथ ही, जिनके यूआरआई पैरामीटर, अनुरोध यूआरआई में मौजूद नहीं होते.
  • टाइप पार्सिंग से जुड़ी गड़बड़ियां: एक्सट्रैक्ट की गई आर्ग्युमेंट वैल्यू, जिन्हें अनुमानित प्रॉपर्टी टाइप में पार्स नहीं किया जा सकता. उदाहरण के लिए, Int प्रॉपर्टी के लिए "abc".

जब कोई मैच नहीं होता है, तो UriDeepLinkMatcher.match null दिखाता है. इससे, बाद के मैच करने वालों का आकलन किया जा सकता है.

डिफ़ॉल्ट वैल्यू, नेस्ट किए गए ऑब्जेक्ट, और enum के साथ कॉन्फ़िगर की गई मुख्य क्लास और मैचर पर विचार करें:

यहां दी गई टेबल में, अलग-अलग अनुरोध यूआरआई के लिए मैच होने वाले नतीजे दिखाए गए हैं:

अनुरोध यूआरआई Decoding Outcome मैच का नतीजा
https://www.example.com/map/paris?zoom=15&style=dark&layer=SATELLITE सफलता (सभी पैरामीटर दिए गए हैं) UriMatchResult(MapKey("paris", 15, LayerOptions("dark", MapLayer.SATELLITE)))
https://www.example.com/map/paris?style=dark Success (zoom defaults to 12, layer to STANDARD) UriMatchResult(MapKey("paris", 12, LayerOptions("dark", MapLayer.STANDARD)))
https://www.example.com/map/paris?zoom=&style=dark Success (खाली छोड़े गए वैकल्पिक क्वेरी पैरामीटर के लिए, डिफ़ॉल्ट 12 का इस्तेमाल किया जाता है) UriMatchResult(MapKey("paris", 12, LayerOptions("dark", MapLayer.STANDARD)))
https://www.example.com/map?style=dark मेल न खाना (ज़रूरी location पैरामीटर मौजूद नहीं है) null
https://www.example.com/map/paris?zoom=close&style=dark मेल नहीं खाता ("close", Int नहीं है) null
https://www.example.com/map/paris?style=dark&layer=HYBRID मेल नहीं खाता ("HYBRID", enum में नहीं है) null

काम न करने वाले कॉन्फ़िगरेशन

अगर आपकी मुख्य क्लास में काम न करने वाले डेटा टाइप शामिल हैं, तो मैच करने के दौरान UriDeepLinkMatcher, null को दिखाने के बजाय एक अपवाद दिखाता है.

  • मैप और मल्टी-डाइमेंशनल कलेक्शन: UriDeepLinkMatcher सिर्फ़ प्रिमिटिव, स्ट्रिंग, एनम या DeepLinkSerializer के साथ एनोटेट किए गए कस्टम टाइप के सिंगल-डाइमेंशनल कलेक्शन के साथ काम करता है. Map टाइप, IllegalArgumentException दिखाता है. वहीं, नेस्ट किए गए कलेक्शन (जैसे, List<List<String>>), SerializationException दिखाते हैं.
  • बिना एनोटेशन वाले कस्टम ऑब्जेक्ट कलेक्शन: कस्टम टाइप के कलेक्शन (जैसे कि List<Filter>) में SerializationException दिखता है. ऐसा तब तक होता है, जब तक एलिमेंट टाइप को DeepLinkSerializer के साथ एनोटेट नहीं किया जाता.
  • अनफ़्लैटन की गई नेस्टेड क्लास: नेस्टेड @Serializable क्लास को DeepLinkSerializer के बिना, किसी एक प्लेसहोल्डर (जैसे कि ?user={user}) पर मैप नहीं किया जा सकता.

UriMatchResult कंपैरिज़न

UriMatchResult इंस्टेंस को इस क्रम में रैंक किया जाता है:

  1. MatchResult टाइप: UriMatchResult को अन्य MatchResult टाइप के मुकाबले ज़्यादा रैंक मिलती है.
  2. एग्ज़ैक्ट पाथ: लिटरल पाथ मैच की रैंक, प्लेसहोल्डर या वाइल्डकार्ड मैच से ज़्यादा होती है.
  3. पाथ आर्ग्युमेंट की संख्या: ज़्यादा पाथ आर्ग्युमेंट वाले यूआरएल को ज़्यादा रैंक मिलती है.
  4. आर्ग्युमेंट की मौजूदगी: आर्ग्युमेंट कैप्चर करने वाले मैच, आर्ग्युमेंट कैप्चर न करने वाले मैच की तुलना में ज़्यादा रैंक करते हैं.
  5. आर्ग्युमेंट की कुल संख्या: आर्ग्युमेंट (पाथ, क्वेरी, फ़्रैगमेंट) की कुल संख्या, फ़ाइनल टाई-ब्रेकर होती है.

UriDeepLinkMatcher को पसंद के मुताबिक बनाएं

UriDeepLinkMatcher एक open क्लास है, जिसे सबक्लास करके यूआरआई मैचिंग और आर्ग्युमेंट एक्सट्रैक्शन के व्यवहार को पसंद के मुताबिक बनाया जा सकता है:

  • matchRequest: यह आने वाले DeepLinkRequest के लिए, टॉप-लेवल मैचिंग एंट्री पॉइंट है. अनुरोध के अतिरिक्त डेटा की जांच करने या यूआरआई मैचिंग से पहले, पसंद के मुताबिक पहले से तय की गई शर्तें लागू करने के लिए, इसे बदलें.
  • matchUri: यह कॉन्फ़िगर किए गए पैटर्न के हिसाब से, DeepLinkUri से मैच करता है. super.matchUri को कॉल करने से पहले, आने वाले यूआरआई को इंटरसेप्ट और नॉर्मलाइज़ करने के लिए, इसे बदलें. उदाहरण के लिए, डाइनैमिक सबडोमेन या लेगसी पाथ फ़ॉर्मैट को फिर से लिखना.
  • matchArguments: यह दिए गए serializer का इस्तेमाल करके, निकाले गए पाथ, क्वेरी, और फ़्रैगमेंट आर्ग्युमेंट मैप को नेविगेशन बटन के इंस्टेंस में डीसीरियलाइज़ करता है. कुंजी को इंस्टैंशिएट करने से पहले, डाइनैमिक वैल्यू इंजेक्ट करने या आर्ग्युमेंट को बदलने के लिए, इसे बदलें.

यहां दिए गए उदाहरण में, मैच करने से पहले लेगसी यूआरएल पाथ प्रीफ़िक्स को सामान्य बनाने के लिए, UriDeepLinkMatcher की सबक्लास बनाने का तरीका बताया गया है: