वेब से ऐप इंस्टॉल तक ट्रैकिंग पैरामीटर्स कैसे पास करें

opoinstall
2026-10-10
5 min read

मोबाइल वेबसाइटों से स्टोर इंस्टॉल तक ट्रैकिंग पैरामीटर्स कैसे पास करें? मोबाइल वेबसाइट से हाल ही में इंस्टॉल किए गए ऐप तक ट्रैकिंग पैरामीटर्स पास करने में OpoInstall वेब JS SDK लोड करना, अलाउलिस्ट किए गए URL पैरामीटर्स को कैप्चर करना, और जब ऐप पहली बार लॉन्च होता है तो नेटिव SDK के माध्यम से समर्थित एट्रिब्यूशन डेटा को रिस्टोर करना शामिल है।

ऐप स्टोर डाउनलोड के दौरान पैरामीटर स्टिचिंग एक ऐसी प्रक्रिया है जो उपयोगकर्ता के मोबाइल लैंडिंग पेज से ऐप स्टोर पर जाने और उसके बाद नए इंस्टॉल किए गए एप्लिकेशन को लॉन्च करने के दौरान योग्य वेब URL पैरामीटर्स को सुरक्षित रखती है। एक वेब SDK अभियान या रेफरल संदर्भ को कैप्चर करता है, जबकि एक प्लेटफॉर्म-समर्थित तंत्र या आस्थगित रेस्टोरेशन सेवा संबंधित पैरामीटर्स को नेटिव ऐप के लिए उपलब्ध करा सकती है। रेस्टोरेशन प्लेटफॉर्म, SDK कॉन्फ़िगरेशन, उपलब्ध मैचिंग सिग्नल और लागू गोपनीयता आवश्यकताओं पर निर्भर करता है।

शब्द परिभाषा संबंधित इकाई खोज उद्देश्य की भूमिका
ट्रैकिंग पैरामीटर्स ट्रैफ़िक संदर्भ, अभियान स्रोत या रेफरल जानकारी की पहचान करने के लिए URL में जोड़े गए की-वैल्यू पेयर्स। URL क्वेरी स्ट्रिंग सूचनात्मक / तकनीकी
ऐप पैरामीटर इंस्टॉलेशन एक आस्थगित पैरामीटर रेस्टोरेशन वर्कफ़्लो जो इंस्टॉलेशन के बाद योग्य वेब संदर्भ को उपलब्ध बनाता है। नेटिव मोबाइल SDK तकनीकी / सूचनात्मक
Google Play इंस्टॉल रेफरर Google Play इंस्टॉलेशन से जुड़ी रेफरल मेटाडेटा प्राप्त करने के लिए एक आधिकारिक Android API। Android SDK तकनीकी

वेब-टू-स्टोर एट्रिब्यूशन गैप: ऐप स्टोर में प्लेटफॉर्म संबंधी बाधाएं

वेब ट्रैकिंग पैरामीटर्स स्वचालित रूप से ऐप-स्टोर इंस्टॉलेशन सीमा को पार नहीं करते हैं।

डिसकनेक्शन बाधा: ऑपरेटिंग सिस्टम सैंडबॉक्स ब्राउज़र संदर्भ को कैसे अलग करते हैं

वेब एनालिटिक्स आमतौर पर URL क्वेरी स्ट्रिंग का उपयोग करते हैं, जिसमें UTM टैग (utm_source, utm_medium, utm_campaign), विज्ञापन क्लिक पहचानकर्ता जैसे gclid और fbclid, और कस्टम रेफरल पैरामीटर्स शामिल हैं।

एक सहभागी वेबसाइट के भीतर, ब्राउज़र API और फर्स्ट-पार्टी एनालिटिक्स सिस्टम इन मानों को अनुमत एनालिटिक्स और अभियान वर्कफ़्लो के लिए कैप्चर कर सकते हैं।

चुनौती तब आती है जब कोई विज़िटर ब्राउज़र छोड़कर ऐप स्टोर इंस्टॉलेशन प्रक्रिया में प्रवेश करता है। ब्राउज़र और नया इंस्टॉल किया गया नेटिव एप्लिकेशन अलग-अलग वातावरण में कार्य करते हैं। ब्राउज़र कुकीज़, सेशन स्टोरेज, और पेज URL पैरामीटर्स इंस्टॉलेशन के बाद एप्लिकेशन के भीतर स्वचालित रूप से उपलब्ध नहीं होते हैं।

परिणामस्वरूप, डेवलपर्स को इंस्टॉल-पूर्व संदर्भ को इंस्टॉल-पश्चात ऐप सेशन के साथ जोड़ने के लिए एक स्टोर-समर्थित रेफरल तंत्र या आस्थगित पैरामीटर रेस्टोरेशन वर्कफ़्लो की आवश्यकता होती है।

प्लेटफॉर्म की विशिष्टताएं: Apple App Store बनाम Google Play Store इंजेशन

Android और iOS अलग-अलग तंत्रों का उपयोग करते हैं, इससे पहले कि पैरामीटर्स एक ऐप अनुबंध में सामान्यीकृत हो जाएं।

मोबाइल ऐप स्टोर रेफरल संदर्भ को पास करने के लिए अलग-अलग दृष्टिकोणों का समर्थन करते हैं।

  • Apple App Store (iOS): एक मानक ऐप स्टोर इंस्टॉलेशन स्वचालित रूप से बाहरी URL क्वेरी पैरामीटर्स को नए इंस्टॉल किए गए एप्लिकेशन के पहले-लॉन्च वातावरण में फॉरवर्ड नहीं करता है। आस्थगित रेस्टोरेशन सेवाएं या स्पष्ट उपयोगकर्ता-मध्यस्थता वर्कफ़्लो Apple की गोपनीयता आवश्यकताओं के अधीन, योग्य संदर्भ को पुनर्प्राप्त करने में मदद कर सकते हैं।
  • Google Play Store (Android): Google आधिकारिक Google Play इंस्टॉल रेफरर API प्रदान करता है। जहां एक ठीक से निर्मित Google Play रेफरल प्रवाह का उपयोग किया जाता है, वहां इंस्टॉल किया गया एप्लिकेशन रेफरर स्ट्रिंग और प्रासंगिक टाइमस्टैम्प सहित समर्थित रेफरल मेटाडेटा प्राप्त कर सकता है।

इन तंत्रों को परस्पर विनिमय योग्य नहीं माना जाना चाहिए। Google Play एक आधिकारिक स्टोर-स्तरीय रेफरल इंटरफ़ेस प्रदान करता है, जबकि iOS पर मनमाना आस्थगित पैरामीटर रेस्टोरेशन के लिए अलग से डिज़ाइन किए गए और नीति-अनुरूप तंत्र की आवश्यकता होती है।

चैनल ROI गणना पर अनएट्रिब्यूटेड इंस्टॉल ट्रैफ़िक का व्यावसायिक प्रभाव

यदि वेब विज़िट और ऐप इंस्टॉलेशन के बीच अभियान पैरामीटर्स खो जाते हैं, तो एनालिटिक्स सिस्टम इंस्टॉलेशन को उसके मूल अभियान के साथ सही ढंग से नहीं जोड़ पाएंगे।

इससे अनएट्रिब्यूटेड इंस्टॉलेशन, अपूर्ण अधिग्रहण रिपोर्टिंग, और निवेश पर रिटर्न (ROI) या ग्राहक अधिग्रहण लागत (CAC) की गलत गणना हो सकती है।

पैरामीटर का नुकसान ऑनबोर्डिंग अनुभव को भी प्रभावित कर सकता है। उदाहरण के लिए, एक वेब रेफरल लिंक में एक आमंत्रण पहचानकर्ता या प्रचार कोड शामिल हो सकता है:

https://example.com/download?inviter_id=USR_1024
https://example.com/download?promo_code=WELCOME50

यदि एप्लिकेशन इन मानों को पुनर्प्राप्त नहीं कर पाता है, तो उपयोगकर्ताओं को उन्हें मैन्युअल रूप से फिर से दर्ज करना पड़ सकता है।

हालांकि, किसी रेफरल या प्रचार मूल्य को रिस्टोर करना स्वचालित रूप से इनाम को अधिकृत नहीं करता है। एप्लिकेशन बैकएंड को स्वतंत्र रूप से पात्रता, मोचन सीमा, और लागू व्यावसायिक नियमों को सत्यापित करना चाहिए।

स्टोर-समर्थित बनाम आस्थगित पैरामीटर तंत्र: Apple App Store बनाम Google Play

Google Play Store तंत्र: नेटिव इंस्टॉल रेफरर API का लाभ उठाना

Android पर, Google Play इंस्टॉल रेफरर API समर्थित इंस्टॉलेशन रेफरल मेटाडेटा प्राप्त करने के लिए एक आधिकारिक तंत्र प्रदान करता है।

Google Play डाउनलोड URL में एक एन्कोडेड referrer पैरामीटर शामिल हो सकता है:

https://play.google.com/store/apps/details?id=com.example.app&referrer=utm_source%3Dfacebook%26inviter_id%3DUSR_1024

इस उदाहरण URL में, एन्कोडेड रेफरर मान का अर्थ है:

utm_source=facebook&inviter_id=USR_1024

इंस्टॉलेशन के बाद, एक नेटिव Android एप्लिकेशन Google Play से उपलब्ध रेफरल जानकारी प्राप्त करने के लिए इंस्टॉल रेफरर क्लाइंट का उपयोग कर सकता है।

क्या OpoInstall वेब SDK का कोई विशिष्ट रिलीज़ स्वचालित रूप से ऐसा URL उत्पन्न, संशोधित या प्रबंधित करता है, इसे इसके तैनात दस्तावेज़ीकरण और व्यवहार के खिलाफ सत्यापित किया जाना चाहिए। Google के आधिकारिक API का अस्तित्व किसी थर्ड-पार्टी SDK के आंतरिक कार्यान्वयन को स्थापित नहीं करता है।

Apple App Store सीमाएं: नेटिव क्वेरी पैरामीटर्स के बिना मानक स्टोर रीडायरेक्ट को संभालना

Apple App Store मनमाने वेब क्वेरी पैरामीटर्स को नए इंस्टॉल किए गए एप्लिकेशन के पहले-लॉन्च कॉलबैक में सीधे पास नहीं करता है।

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

SDK-आधारित वर्कफ़्लो के लिए, डेवलपर्स को विक्रेता द्वारा प्रलेखित कार्यक्षमता और तैनात SDK संस्करण द्वारा उपयोग की जाने वाली मैचिंग विधियों के बीच अंतर करना चाहिए।

किसी भी मैचिंग या डेटा संग्रह विधि को Apple की गोपनीयता नीतियों का अनुपालन करना चाहिए। विशेष रूप से, एक एट्रिब्यूशन कार्यान्वयन को निषिद्ध डिवाइस फिंगरप्रिंटिंग पर भरोसा नहीं करना चाहिए या यह नहीं मानना चाहिए कि ATT अनुमति किसी अन्य निषिद्ध मैचिंग विधि को स्वीकार्य बनाती है।

यूनिवर्सल लिंक पहले से इंस्टॉल किए गए एप्लिकेशन में समर्थित लिंक को रूट करने के लिए उपयोगी हैं, लेकिन वे स्वयं यह गारंटी नहीं देते हैं कि मनमाने वेब क्वेरी पैरामीटर्स एक नए ऐप स्टोर इंस्टॉलेशन के बाद भी जीवित रहेंगे।

क्रॉस-प्लेटफॉर्म आर्किटेक्चरल विचलन: एकीकृत पैरामीटर अनुबंध बनाना

हालांकि Android और iOS अलग-अलग प्लेटफॉर्म तंत्र का उपयोग करते हैं, एक एप्लिकेशन पुनर्प्राप्त मानों को एक साझा एप्लिकेशन-स्तरीय स्कीमा में सामान्यीकृत कर सकता है।

उदाहरण के लिए:

{
  "utm_source": "facebook",
  "utm_medium": "paid_social",
  "utm_campaign": "summer_sale",
  "inviter_id": "USR_1024",
  "promo_code": "WELCOME50"
}

यह JSON ऑब्जेक्ट एक एप्लिकेशन-परिभाषित सामान्यीकृत पैरामीटर अनुबंध का प्रतिनिधित्व करता है, न कि OpoInstall SDK के हर रिलीज़ से एक गारंटीकृत शाब्दिक प्रतिक्रिया प्रारूप।

एप्लिकेशन को इन फ़ील्ड्स को दो श्रेणियों में विभाजित करना चाहिए:

  • मार्केटिंग एट्रिब्यूशन: utm_source, utm_medium, और utm_campaign।
  • रेफरल और प्रचार कार्य: inviter_id और promo_code।

मार्केटिंग एट्रिब्यूशन को एक अधिकृत एनालिटिक्स पाइपलाइन में सबमिट किया जा सकता है। रेफरल और प्रचार कार्यों के लिए एप्लिकेशन द्वारा कोई भी लाभ देने से पहले स्वतंत्र सर्वर-साइड प्राधिकरण की आवश्यकता होती है।

स्टोर रीडायरेक्शन को जोड़ने में संदर्भगत पेलोड कैशिंग की भूमिका

आस्थगित रेस्टोरेशन सेवाओं को आम तौर पर इंस्टॉलेशन संदर्भ के लिए सीमित प्रतिधारण अवधि की आवश्यकता होती है।

लागू प्रतिधारण विंडो, रेस्टोरेशन व्यवहार, और मैच उपलब्धता तैनात सेवा, SDK कॉन्फ़िगरेशन, नेटवर्क स्थितियों, प्लेटफॉर्म सीमाओं और गोपनीयता आवश्यकताओं पर निर्भर करती है।

इंजीनियरिंग टीमों को असमर्थित सटीकता दावों को अपनाने के बजाय अपने स्वयं के इंस्टॉलेशन कोहॉर्ट का उपयोग करके रेस्टोरेशन परिणामों को मापना चाहिए।

गोपनीयता-जागरूक आस्थगित संदर्भ आर्किटेक्चर और प्लेटफॉर्म सीमाएं

iOS पर सिस्टम पेस्टबोर्ड सीमाएं: पारदर्शिता बैनर और UIPasteControl इंटेंट मैकेनिक्स

कुछ ऐतिहासिक आस्थगित-लिंकिंग कार्यान्वयनों ने एप्लिकेशन के बीच अस्थायी संदर्भ ले जाने के लिए सिस्टम पेस्टबोर्ड का उपयोग किया।

हालांकि, iOS क्रॉस-एप्लिकेशन पेस्टबोर्ड एक्सेस को प्रतिबंधित करता है और उपयोगकर्ताओं के सामने उजागर करता है।

  • iOS 14: किसी अन्य एप्लिकेशन से कॉपी की गई सामग्री को पढ़ने से पेस्टबोर्ड एक्सेस सूचना ट्रिगर हो सकती है।
  • iOS 16 और बाद के संस्करण: कुछ प्रोग्रामेटिक पेस्ट ऑपरेशन अनुमति प्रॉम्प्ट ट्रिगर कर सकते हैं। UIPasteControl जैसे नियंत्रण उपयोगकर्ता द्वारा शुरू की गई पेस्ट इंटरैक्शन का समर्थन करते हैं।

परिणामस्वरूप, सामान्य पेस्टबोर्ड एक्सेस को एक अदृश्य या अप्रतिबंधित इंस्टॉलेशन पैरामीटर परिवहन चैनल के रूप में नहीं माना जाना चाहिए।

पेस्टबोर्ड-संबंधित कार्यक्षमता का उपयोग करने वाले एप्लिकेशन को उपयोगकर्ता की अपेक्षाओं के अनुसार इंटरैक्शन को उपयुक्त बनाना चाहिए और अस्वीकृत अनुमति या गायब सामग्री को शालीनता से संभालना चाहिए।

Android फॉरग्राउंड क्लिपबोर्ड प्रतिबंध: नेविगेशन बाधाएं और स्वचालित सफाई

Android क्लिपबोर्ड एक्सेस पर भी प्रतिबंध लागू करता है।

  • Android 10 और बाद के संस्करण: क्लिपबोर्ड एक्सेस उन एप्लिकेशन के लिए प्रतिबंधित है जो योग्य फॉरग्राउंड संदर्भ में नहीं हैं, जो प्लेटफॉर्म-परिभाषित अपवादों के अधीन है।
  • Android 13 और बाद के संस्करण: Android क्लिपबोर्ड सामग्री के लिए क्लिपबोर्ड-संबंधित उपयोगकर्ता इंटरफ़ेस प्रतिक्रिया और स्वचालित समाशोधन व्यवहार प्रदान करता है।

एप्लिकेशन को यह नहीं मानना चाहिए कि क्लिपबोर्ड डेटा को चुपचाप पुनर्प्राप्त किया जा सकता है या यह अनिश्चित काल तक उपलब्ध रहता है।

क्लिपबोर्ड एक्सेस वैकल्पिक होना चाहिए और इसे एक मानित प्राथमिक एट्रिब्यूशन चैनल के रूप में कार्य करने के बजाय उपयुक्त उपयोगकर्ता-सामने वाले वर्कफ़्लो तक सीमित होना चाहिए।

Apple उपयोगकर्ता गोपनीयता और डेटा उपयोग नीतियों का कड़ाई से पालन: डिवाइस फिंगरप्रिंटिंग को प्रतिबंधित करना

Apple डिवाइस और पर्यावरण विशेषताओं के संयोजन के माध्यम से उपयोगकर्ताओं या उपकरणों की पहचान करने के लिए उपयोग की जाने वाली डिवाइस फिंगरप्रिंटिंग को प्रतिबंधित करता है।

एक कार्यान्वयन को Apple की नीतियों के उल्लंघन में IP पते, उपयोगकर्ता एजेंट जानकारी, प्रदर्शन विशेषताओं, या अन्य डिवाइस संकेतों के संयोजन से स्थायी या संभाव्य पहचानकर्ता नहीं बनाने चाहिए।

ऐप ट्रैकिंग पारदर्शिता अनुमति देना निषिद्ध फिंगरप्रिंटिंग विधियों को अनुमेय नहीं बनाता है।

किसी भी थर्ड-पार्टी आस्थगित पैरामीटर रेस्टोरेशन सेवा के लिए, डेवलपर्स को तैनात SDK के वास्तविक डेटा संग्रह, मैचिंग व्यवहार, गोपनीयता प्रकटीकरण और प्लेटफॉर्म नीति आवश्यकताओं की समीक्षा करनी चाहिए।

एक गोपनीयता-जागरूक एकीकरण को डेटा न्यूनीकरण, पारदर्शी उपयोगकर्ता इंटरैक्शन, और समर्थित प्लेटफॉर्म तंत्र को प्राथमिकता देनी चाहिए।

सुरक्षा और विश्वास सीमाएं: पैरामीटर जीवनचक्र और सर्वर प्राधिकरण का प्रबंधन

पुनर्प्राप्त इंस्टॉल पैरामीटर्स के लिए अलग एनालिटिक्स और बैकएंड प्राधिकरण प्रसंस्करण की आवश्यकता होती है।

सभी रिस्टोर किए गए पैरामीटर्स को अविश्वसनीय इनपुट माना जाना चाहिए।

मार्केटिंग टैग और रेफरल टोकन संपादन योग्य URL या अविश्वसनीय क्लाइंट अनुरोधों से उत्पन्न हो सकते हैं। केवल उनकी उपस्थिति यह स्थापित नहीं करती है कि कोई अभियान वैध है या कोई उपयोगकर्ता इनाम के लिए पात्र है।

एप्लिकेशन को इन सिद्धांतों का पालन करना चाहिए:

  • अलाउलिस्टेड मान: केवल स्पष्ट रूप से समर्थित कुंजियों और सीमित मानों को स्वीकार करें।
  • एट्रिब्यूशन को प्राधिकरण से अलग करें: UTM मान ट्रैफ़िक की उत्पत्ति का वर्णन कर सकते हैं; उन्हें स्वतंत्र रूप से प्रचार लाभों को अधिकृत नहीं करना चाहिए।
  • समय-सीमित लंबित रिकॉर्ड: केवल प्रसंस्करण के लिए आवश्यक जानकारी रखें, जो एक एप्लिकेशन-परिभाषित समाप्ति विंडो के अधीन है।
  • संरक्षित भंडारण: लंबित टोकन की संवेदनशीलता के लिए उपयुक्त भंडारण का उपयोग करें, जैसे कि Android कीस्टोर-समर्थित डिज़ाइन या iOS कीचेन सेवाएँ जहां आवश्यक हो।
  • स्वतंत्र डिलीवरी परिणाम: मार्केटिंग और रिवॉर्ड पैरामीटर दोनों वाले रिकॉर्ड के लिए, एप्लिकेशन को आवश्यक परिणामों को स्वतंत्र रूप से ट्रैक करना चाहिए।
  • सर्वर-साइड रिवॉर्ड सत्यापन: रेफरल क्रेडिट, प्रचार छूट, और इसी तरह की पात्रता को एक प्रमाणित एप्लिकेशन बैकएंड द्वारा अनुमोदित किया जाना चाहिए।
  • आइडम्पोटेंट रिवॉर्ड एप्लिकेशन: बैकएंड को लेनदेन-स्तरीय आइडम्पोटेंसी और व्यावसायिक-स्तरीय विशिष्टता बाधाओं को लागू करना चाहिए ताकि दोहराए गए क्लाइंट अनुरोध एक-बार के पुरस्कारों की नकल न कर सकें।

नीचे दिया गया कोड पैरामीटर सीमा और होस्ट एप्लिकेशन की एकीकरण जिम्मेदारियों को दर्शाता है। यह पूरा उत्पादन-ग्रेड भंडारण, एनालिटिक्स या रिवॉर्ड लेनदेन प्रणाली प्रदान करने का प्रयास नहीं करता है।

एंड-टू-एंड कार्यान्वयन: नेटिव रेस्टोरेशन के लिए वेब पैरामीटर्स को कैप्चर करना

वेब क्वेरी पैरामीटर्स को सैनिटाइज़ करना: HTML बूटस्ट्रैप, अलाउलिस्ट पार्सिंग, और वेब JS SDK सेटअप

एक लैंडिंग पेज स्पष्ट रूप से समर्थित क्वेरी पैरामीटर्स को कैप्चर कर सकता है और उन्हें एक सीमित पेलोड के रूप में वेब SDK को पास कर सकता है।

निम्नलिखित उदाहरण प्रदर्शित करता है:

  • SDK को उसके कॉन्फ़िगर किए गए स्रोत से लोड करना।
  • एक सामान्य HTTPS डाउनलोड फॉलबैक लिंक को संरक्षित करना।
  • केवल समर्थित पैरामीटर कुंजियों को स्वीकार करना।
  • संकीर्ण वर्ण और लंबाई नीति के बाहर के मानों को अस्वीकार करना।
  • पेज के डाउनलोड बटन के साथ एक SDK डाउनलोड कार्रवाई को कनेक्ट करना।

SDK कंस्ट्रक्टर, कॉन्फ़िगरेशन कुंजियाँ, और विधियाँ प्रतिनिधि हैं। प्रकाशन या तैनाती से पहले सटीक OpoInstall वेब SDK रिलीज़ के खिलाफ उनके हस्ताक्षरों को सत्यापित करें।

<!-- CODE_BLOCK_01: Representative HTML Bootstrap and Web SDK Integration -->
<!-- File: landing_page.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Application Download</title>
</head>
<body>
    <!-- Replace with a real HTTPS download or store-routing URL. -->
    <a
        id="download-app-btn"
        href="https://app.example.com/store-download"
    >
        Download App
    </a>

    <!-- Verify the official CDN URL against the deployed SDK version. -->
    <script src="https://web.cdn.opoinstallcloud.com/openinstall.js"></script>

    <script>
    (function () {
        "use strict";

        function getSanitizedQueryParams() {
            var allowedKeys = new Set([
                "utm_source",
                "utm_medium",
                "utm_campaign",
                "inviter_id",
                "promo_code"
            ]);

            var validPattern = /^[A-Za-z0-9_.-]{1,64}$/;
            var result = Object.create(null);

            try {
                var query = new URLSearchParams(window.location.search);

                query.forEach(function (value, key) {
                    if (
                        allowedKeys.has(key) &&
                        validPattern.test(value) &&
                        !Object.prototype.hasOwnProperty.call(result, key)
                    ) {
                        result[key] = value;
                    }
                });
            } catch (error) {
                console.warn("Unable to parse URL parameters.");
                return Object.create(null);
            }

            return result;
        }

        var downloadButton = document.getElementById(
            "download-app-btn"
        );

        // Keep the anchor href as the normal browser fallback.
        if (!downloadButton) {
            return;
        }

        if (typeof OpenInstall === "undefined") {
            console.warn(
                "Web SDK unavailable; using the download link."
            );
            return;
        }

        var customParams = getSanitizedQueryParams();

        try {
            new OpenInstall({
                appKey: "OPOINSTALL_APPKEY_PLACEHOLDER",
                data: customParams,

                onready: function () {
                    var sdkClient = this;

                    downloadButton.addEventListener(
                        "click",
                        function (event) {
                            try {
                                // Representative SDK method.
                                // Verify its behavior and async failure
                                // handling for the deployed release.
                                sdkClient.wakeupOrInstall();
                                event.preventDefault();
                            } catch (error) {
                                console.warn(
                                    "SDK action failed; browser will use fallback."
                                );

                                // Do not prevent the default anchor action.
                            }
                        }
                    );
                }
            });
        } catch (error) {
            console.warn(
                "Web SDK initialization failed; using fallback link."
            );
        }
    })();
    </script>
</body>
</html>

मान नीति जानबूझकर केवल अक्षरों, अंकों, अंडरस्कोर, हाइफ़न और बिंदुओं को स्वीकार करती है, जिसकी अधिकतम लंबाई 64 वर्ण है।

स्थान या अन्य वर्णों वाले मानों को इस संदर्भ कार्यान्वयन में बाहर रखा गया है। व्यापक UTM नामकरण आवश्यकताओं वाली टीमों को सभी URL मानों के समर्थित होने की चुपचाप कल्पना करने के बजाय एक उपयुक्त फ़ील्ड-विशिष्ट स्कीमा को परिभाषित और परीक्षण करना चाहिए।

इसी तरह, विज्ञापन क्लिक पहचानकर्ता जैसे gclid और fbclid पर सामान्य वेब एट्रिब्यूशन अवधारणाओं के रूप में चर्चा की जाती है, लेकिन उन्हें इस नमूना अलाउलिस्ट में शामिल नहीं किया गया है। उनका समर्थन करने के लिए अलग डेटा संग्रह, प्रतिधारण और गोपनीयता समीक्षा की आवश्यकता होती है।

जब SDK लोड नहीं होता है या इनिशियलाइज़ नहीं हो पाता है, तो फॉलबैक एंकर उपलब्ध रहता है। चूंकि SDK संचालन एसिंक्रोनस रूप से विफल हो सकते हैं, इसलिए उत्पादन एकीकरण को SDK के प्रलेखित त्रुटि हैंडलिंग और रीडायरेक्ट व्यवहार का अतिरिक्त रूप से पालन करना चाहिए; एक सिंक्रोनस try/catch अपने आप में एक पूर्ण एसिंक्रोनस फॉलबैक रणनीति नहीं है।

Android नेटिव कार्यान्वयन: SDK सेटअप, पैरामीटर सत्यापन, और होस्ट एप्लिकेशन अनुबंध

इंस्टॉलेशन के बाद, Android एप्लिकेशन नेटिव SDK से समर्थित पैरामीटर्स का अनुरोध कर सकता है और उन्हें एक एप्लिकेशन-परिभाषित रिकॉर्ड में सामान्यीकृत कर सकता है।

नीचे दिया गया नमूना जानबूझकर जिम्मेदारियों को अलग रखता है:

  1. OpoInstall SDK एप्लिकेशन की मुख्य प्रक्रिया में इनिशियलाइज़ होता है।
  2. नेटिव कॉलबैक एक उम्मीदवार पेलोड प्रदान करता है।
  3. एप्लिकेशन पेलोड को सत्यापित और सामान्यीकृत करता है।
  4. एप्लिकेशन होस्ट-प्रदान किए गए स्टोरेज इंटरफ़ेस के माध्यम से रिकॉर्ड को सहेजता है।
  5. एक होस्ट-प्रदान किया गया प्रसंस्करण घटक मार्केटिंग एट्रिब्यूशन और रिवॉर्ड प्राधिकरण का समन्वय करता है।
  6. एप्लिकेशन रिकॉर्ड को तभी पूर्ण के रूप में चिह्नित करता है जब वह घटक एक सत्यापित प्रसंस्करण परिणाम की रिपोर्ट करता है।

महत्वपूर्ण: होस्ट इंटरफ़ेस एप्लिकेशन-परिभाषित अनुबंध हैं, न कि OpoInstall API। इस उदाहरण के लिए होस्ट एप्लिकेशन को कार्यान्वयन प्रदान करने की आवश्यकता होती है। इसमें असुरक्षित फॉलबैक स्टोरेज, सिम्युलेटेड एनालिटिक्स डिलीवरी, या मॉक रिवॉर्ड प्राधिकरण प्रतिक्रिया शामिल नहीं है।

// CODE_BLOCK_02: Representative Android Integration (Kotlin)
// File: CustomApplication.kt and MainActivity.kt
//
// Verify OpoInstall imports and callbacks against the deployed AAR.
// Host implementations must be provided before parameter processing.

package com.example.app

import android.app.ActivityManager
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Process
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.opoinstall.api.OpoInstall
import com.opoinstall.api.OpoData
import com.opoinstall.api.OpoError
import com.opoinstall.api.ResultCallBack
import org.json.JSONObject
import java.util.UUID

enum class ParamFetchState {
    NOT_STARTED,
    FETCHING,
    RECEIVED,
    APPLIED,
    REJECTED,
    NO_MATCH,
    RETRYABLE_FAILURE
}

data class PendingAttributionRecord(
    val utmSource: String?,
    val utmMedium: String?,
    val utmCampaign: String?,
    val inviterId: String?,
    val promoCode: String?,
    val idempotencyKey: String,
    val createdAt: Long,
    val expiresAt: Long
) {
    val hasAttributionData: Boolean
        get() = listOf(
            utmSource, utmMedium, utmCampaign
        ).any { !it.isNullOrEmpty() }

    val hasRewardData: Boolean
        get() = !inviterId.isNullOrEmpty() ||
                !promoCode.isNullOrEmpty()

    val hasAnyData: Boolean
        get() = hasAttributionData || hasRewardData

    fun isValid(): Boolean {
        val now = System.currentTimeMillis()
        val pattern = Regex("^[A-Za-z0-9_.-]{1,64}$")

        val values = listOf(
            utmSource, utmMedium, utmCampaign,
            inviterId, promoCode
        )

        val validFields = values.all {
            it == null || pattern.matches(it)
        }

        val validWindow =
            expiresAt > createdAt &&
            expiresAt - createdAt <= 48L * 60 * 60 * 1000 &&
            now >= createdAt &&
            now <= expiresAt

        val validId = try {
            UUID.fromString(idempotencyKey)
            true
        } catch (_: IllegalArgumentException) {
            false
        }

        return hasAnyData &&
               validFields &&
               validWindow &&
               validId
    }
}

// Host-defined secure persistence contract.
// The implementation must distinguish missing data from
// storage failures and handle account binding where needed.
interface PendingTransactionStore {
    fun save(record: PendingAttributionRecord): Boolean
    fun load(): PendingAttributionRecord?
    fun clear(): Boolean
}

// Host-defined coordinator. Its implementation is responsible
// for independent telemetry/reward acknowledgments,
// idempotency, retry handling, and transaction identity checks.
interface InstallParameterProcessor {
    fun process(
        record: PendingAttributionRecord,
        onComplete: (ProcessingOutcome) -> Unit
    )
}

enum class ProcessingOutcome {
    COMPLETED,
    REJECTED,
    RETRYABLE_FAILURE
}

// These are application dependencies, NOT OpoInstall SDK APIs.
object HostAppDependencies {
    var transactionStore: PendingTransactionStore? = null
    var parameterProcessor: InstallParameterProcessor? = null

    val isConfigured: Boolean
        get() = transactionStore != null &&
                parameterProcessor != null
}

class CustomApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        if (isMainProcess()) {
            OpoInstall.initialize(this)

            // The host app must configure dependencies here
            // using its actual DI/bootstrap mechanism.
            //
            // HostAppDependencies.transactionStore =
            //     hostProvidedProtectedStore
            //
            // HostAppDependencies.parameterProcessor =
            //     hostProvidedInstallParameterProcessor
        }
    }

    private fun isMainProcess(): Boolean {
        val manager = getSystemService(
            Context.ACTIVITY_SERVICE
        ) as ActivityManager

        val currentPid = Process.myPid()

        return manager.runningAppProcesses?.any {
            it.pid == currentPid &&
            it.processName == packageName
        } == true
    }
}

class MainActivity : AppCompatActivity() {

    private val mainHandler = Handler(Looper.getMainLooper())

    private var state = ParamFetchState.NOT_STARTED
    private var activeRecord: PendingAttributionRecord? = null
    private var processingInFlight = false

    private val transactionTtlMs =
        24L * 60 * 60 * 1000

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startParameterFlow()
    }

    private fun startParameterFlow() {
        val store = HostAppDependencies.transactionStore
        val processor = HostAppDependencies.parameterProcessor

        if (store == null || processor == null) {
            Log.w(
                "OpoInstall",
                "Host dependencies unavailable; processing suspended"
            )
            state = ParamFetchState.RETRYABLE_FAILURE
            return
        }

        // Representative record recovery.
        // Production storage must report read failures separately
        // from a confirmed absence of a pending record.
        val existingRecord = try {
            store.load()
        } catch (error: Exception) {
            state = ParamFetchState.RETRYABLE_FAILURE
            return
        }

        if (existingRecord != null) {
            if (existingRecord.isValid()) {
                activeRecord = existingRecord
                state = ParamFetchState.RECEIVED
                processRecord(existingRecord)
            } else {
                // Invalid or expired records are not processed.
                if (!store.clear()) {
                    state = ParamFetchState.RETRYABLE_FAILURE
                    return
                }

                requestInstallParameters()
            }
        } else {
            requestInstallParameters()
        }
    }

    private fun requestInstallParameters() {
        if (!HostAppDependencies.isConfigured) {
            state = ParamFetchState.RETRYABLE_FAILURE
            return
        }

        if (state == ParamFetchState.FETCHING ||
            state == ParamFetchState.APPLIED ||
            state == ParamFetchState.NO_MATCH ||
            processingInFlight
        ) {
            return
        }

        state = ParamFetchState.FETCHING

        // Representative SDK callback.
        // Validate signature against the deployed AAR.
        OpoInstall.getInstance().getInstallParam(
            object : ResultCallBack<OpoData> {

                override fun onResult(opoData: OpoData?) {
                    mainHandler.post {
                        if (state != ParamFetchState.FETCHING) {
                            return@post
                        }

                        val rawData: Any? = opoData?.data

                        val payload = when (rawData) {
                            is String -> rawData
                            is JSONObject -> rawData.toString()
                            is Map<*, *> -> try {
                                JSONObject(rawData).toString()
                            } catch (_: Exception) {
                                null
                            }
                            else -> null
                        }

                        val record = payload?.let {
                            parseAndSanitizeRawPayload(it)
                        }

                        if (record == null) {
                            // No eligible data was recovered.
                            // This does not establish an organic install.
                            state = ParamFetchState.NO_MATCH
                            return@post
                        }

                        val store =
                            HostAppDependencies.transactionStore

                        if (store == null ||
                            !HostAppDependencies.isConfigured
                        ) {
                            state = ParamFetchState.RETRYABLE_FAILURE
                            return@post
                        }

                        activeRecord = record

                        // Do not claim durable recovery if saving fails.
                        val saved = try {
                            store.save(record)
                        } catch (_: Exception) {
                            false
                        }

                        if (!saved) {
                            Log.w(
                                "OpoInstall",
                                "Pending record could not be persisted"
                            )
                            state = ParamFetchState.RETRYABLE_FAILURE
                            return@post
                        }

                        state = ParamFetchState.RECEIVED
                        processRecord(record)
                    }
                }

                override fun onError(error: OpoError?) {
                    mainHandler.post {
                        if (state == ParamFetchState.FETCHING) {
                            Log.w(
                                "OpoInstall",
                                "Install parameter retrieval failed"
                            )
                            state = ParamFetchState.RETRYABLE_FAILURE
                        }
                    }
                }
            }
        )
    }

    private fun parseAndSanitizeRawPayload(
        rawJson: String
    ): PendingAttributionRecord? {
        return try {
            if (rawJson.length > 4096) return null

            val json = JSONObject(rawJson)
            val pattern = Regex("^[A-Za-z0-9_.-]{1,64}$")

            fun field(key: String): String? =
                (json.opt(key) as? String)?.takeIf {
                    pattern.matches(it)
                }

            val now = System.currentTimeMillis()

            val record = PendingAttributionRecord(
                utmSource = field("utm_source"),
                utmMedium = field("utm_medium"),
                utmCampaign = field("utm_campaign"),
                inviterId = field("inviter_id"),
                promoCode = field("promo_code"),
                idempotencyKey = UUID.randomUUID().toString(),
                createdAt = now,
                expiresAt = now + transactionTtlMs
            )

            record.takeIf { it.isValid() }
        } catch (_: Exception) {
            null
        }
    }

    private fun processRecord(
        record: PendingAttributionRecord
    ) {
        val processor = HostAppDependencies.parameterProcessor
        val store = HostAppDependencies.transactionStore

        if (processor == null || store == null ||
            !record.isValid()
        ) {
            state = ParamFetchState.RETRYABLE_FAILURE
            return
        }

        if (processingInFlight) return

        processingInFlight = true

        // The host processor must not report COMPLETED until
        // all required channel-specific outcomes are confirmed.
        processor.process(record) { outcome ->
            mainHandler.post {
                // Ignore superseded or stale transactions.
                if (activeRecord?.idempotencyKey !=
                    record.idempotencyKey
                ) {
                    return@post
                }

                processingInFlight = false

                when (outcome) {
                    ProcessingOutcome.COMPLETED -> {
                        finalizeRecord(
                            record,
                            ParamFetchState.APPLIED
                        )
                    }

                    ProcessingOutcome.REJECTED -> {
                        finalizeRecord(
                            record,
                            ParamFetchState.REJECTED
                        )
                    }

                    ProcessingOutcome.RETRYABLE_FAILURE -> {
                        state =
                            ParamFetchState.RETRYABLE_FAILURE
                    }
                }
            }
        }
    }

    private fun finalizeRecord(
        record: PendingAttributionRecord,
        terminalState: ParamFetchState
    ) {
        val store = HostAppDependencies.transactionStore
            ?: run {
                state = ParamFetchState.RETRYABLE_FAILURE
                return
            }

        if (activeRecord?.idempotencyKey !=
            record.idempotencyKey
        ) {
            return
        }

        // This example intentionally leaves durable terminal
        // journaling and atomic cleanup to the host store.
        // clear() must report whether cleanup succeeded.
        val cleared = try {
            store.clear()
        } catch (_: Exception) {
            false
        }

        if (!cleared) {
            state = ParamFetchState.RETRYABLE_FAILURE
            return
        }

        activeRecord = null
        state = terminalState

        Log.i(
            "OpoInstall",
            "Install parameter processing resolved"
        )
    }
}

Android नमूने में जानबूझकर PendingTransactionStore या InstallParameterProcessor का डिफ़ॉल्ट कार्यान्वयन शामिल नहीं है।

होस्ट एप्लिकेशन को वर्कफ़्लो शुरू करने से पहले उन्हें प्रदान करना होगा।

विशेष रूप से, प्रोसेसर को केवल इसलिए COMPLETED नहीं लौटाना चाहिए क्योंकि एक लॉगिंग स्टेटमेंट चला है या एक एसिंक्रोनस अनुरोध शुरू किया गया है। एक पूर्ण परिणाम वास्तविक पेलोड के लिए प्रसंस्करण आवश्यकताओं के अनुरूप होना चाहिए:

  • UTM-ओनली पेलोड: आवश्यक एट्रिब्यूशन इवेंट को कॉन्फ़िगर किए गए एनालिटिक्स सिस्टम या टिकाऊ इवेंट कतार द्वारा मज़बूती से स्वीकार किया जाता है।
  • रिवॉर्ड-ओनली पेलोड: प्रमाणित बैकएंड एक स्वीकृत टर्मिनल प्राधिकरण परिणाम लौटाता है।
  • मिश्रित UTM और रिवॉर्ड पेलोड: दोनों आवश्यक चैनल स्वतंत्र रूप से परिभाषित परिणामों तक पहुँचते हैं, और एक चैनल दूसरे द्वारा आवश्यक कार्य को समय से पहले नहीं हटा सकता है।

यदि होस्ट एप्लिकेशन को क्रॉस-प्रक्रिया रिकवरी की आवश्यकता है, तो प्रोसेसर और संरक्षित स्टोर को अतिरिक्त रूप से पर्याप्त चैनल-विशिष्ट प्रगति को बनाए रखना चाहिए और स्थिर लेनदेन पहचानकर्ताओं को संरक्षित करना चाहिए।

ऊपर दी गई गतिविधि एकीकरण सीमा को दर्शाती है; यह उन एप्लिकेशन-विशिष्ट कार्यान्वयनों का विकल्प नहीं है।

iOS नेटिव कार्यान्वयन: SDK रेस्टोरेशन और एप्लिकेशन एकीकरण अनुबंध

iOS एकीकरण उसी सीमा का पालन करता है।

नेटिव SDK उम्मीदवार इंस्टॉलेशन पैरामीटर्स की आपूर्ति करता है। एप्लिकेशन पेलोड को सत्यापित करता है, होस्ट-प्रदान किए गए स्टोरेज घटक के माध्यम से एक लंबित रिकॉर्ड को बनाए रखता है, और व्यावसायिक प्रसंस्करण को एक एप्लिकेशन-स्वामित्व वाले समन्वयक को सौंपता है।

कोड प्रतिनिधि है और इसे तैनात OpoInstall iOS SDK रिलीज़ के मॉड्यूल नाम, डेलिगेट प्रोटोकॉल और कॉलबैक हस्ताक्षरों के अनुकूल बनाया जाना चाहिए।

// CODE_BLOCK_03: Representative iOS Integration (Swift)
// File: AppDelegate.swift
//
// Verify the module and SDK methods against the deployed
// OpoInstall framework version.

import UIKit
import libOpoInstallSDK

enum ParamFetchState: String {
    case notStarted = "NOT_STARTED"
    case fetching = "FETCHING"
    case received = "RECEIVED"
    case applied = "APPLIED"
    case rejected = "REJECTED"
    case noMatch = "NO_MATCH"
    case retryableFailure = "RETRYABLE_FAILURE"
}

struct PendingAttributionRecord: Codable {
    let utmSource: String?
    let utmMedium: String?
    let utmCampaign: String?
    let inviterId: String?
    let promoCode: String?
    let idempotencyKey: String
    let createdAt: TimeInterval
    let expiresAt: TimeInterval

    var hasAttributionData: Bool {
        return [
            utmSource, utmMedium, utmCampaign
        ].contains { !$0.isNilOrEmpty }
    }

    var hasRewardData: Bool {
        return !inviterId.isNilOrEmpty ||
               !promoCode.isNilOrEmpty
    }

    var hasAnyData: Bool {
        return hasAttributionData || hasRewardData
    }

    var isValid: Bool {
        let now = Date().timeIntervalSince1970
        let window = expiresAt - createdAt

        let pattern = "^[A-Za-z0-9_.-]{1,64}$"

        let fields = [
            utmSource, utmMedium, utmCampaign,
            inviterId, promoCode
        ]

        let validFields = fields.allSatisfy { field in
            guard let field = field else { return true }
            return field.range(
                of: pattern,
                options: .regularExpression
            ) != nil
        }

        return hasAnyData &&
               validFields &&
               UUID(uuidString: idempotencyKey) != nil &&
               window > 0 &&
               window <= 48 * 60 * 60 &&
               now >= createdAt &&
               now <= expiresAt
    }
}

private extension Optional where Wrapped == String {
    var isNilOrEmpty: Bool {
        return self?.isEmpty ?? true
    }
}

// Host-provided protected persistence contract.
protocol PendingTransactionStore {
    func save(_ record: PendingAttributionRecord) -> Bool
    func load() throws -> PendingAttributionRecord?
    func clear() -> Bool
}

enum ProcessingOutcome {
    case completed
    case rejected
    case retryableFailure
}

// Host-provided coordinator for analytics and reward processing.
protocol InstallParameterProcessor {
    func process(
        record: PendingAttributionRecord,
        completion: @escaping (ProcessingOutcome) -> Void
    )
}

// These are application contracts, not OpoInstall APIs.
struct HostAppDependencies {
    static var transactionStore: PendingTransactionStore?
    static var parameterProcessor: InstallParameterProcessor?

    static var isConfigured: Bool {
        return transactionStore != nil &&
               parameterProcessor != nil
    }
}

@UIApplicationMain
class AppDelegate:
    UIResponder,
    UIApplicationDelegate,
    OpoInstallDelegate {

    var window: UIWindow?

    private var state: ParamFetchState = .notStarted
    private var activeRecord: PendingAttributionRecord?
    private var processingInFlight = false

    private let transactionTTL: TimeInterval =
        24 * 60 * 60

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions:
            [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        // Representative SDK initialization.
        OpoInstallSDK.initWith(self)

        // The host app must register its actual dependencies
        // before starting parameter processing.
        //
        // HostAppDependencies.transactionStore =
        //     hostProvidedProtectedStore
        //
        // HostAppDependencies.parameterProcessor =
        //     hostProvidedInstallParameterProcessor

        startParameterFlow()
        return true
    }

    private func startParameterFlow() {
        guard HostAppDependencies.isConfigured,
              let store = HostAppDependencies.transactionStore
        else {
            print(
                "OpoInstall: Required host dependencies unavailable"
            )
            state = .retryableFailure
            return
        }

        do {
            if let saved = try store.load() {
                if saved.isValid {
                    activeRecord = saved
                    state = .received
                    processRecord(saved)
                    return
                }

                guard store.clear() else {
                    state = .retryableFailure
                    return
                }
            }
        } catch {
            // A read error is not equivalent to an empty store.
            state = .retryableFailure
            return
        }

        requestInstallParameters()
    }

    private func requestInstallParameters() {
        guard HostAppDependencies.isConfigured,
              state != .fetching,
              state != .applied,
              state != .noMatch,
              !processingInFlight
        else {
            return
        }

        guard let manager = OpoInstallSDK.defaultManager()
        else {
            state = .retryableFailure
            return
        }

        state = .fetching

        // Representative callback signature.
        manager.getInstallParmsCompleted({
            [weak self] (appData: OpoinstallData?) in

            DispatchQueue.main.async {
                guard let self = self,
                      self.state == .fetching
                else {
                    return
                }

                let rawData: Any? = appData?.data

                guard let record =
                    self.parseAndSanitizeRawPayload(rawData)
                else {
                    // No eligible custom parameters recovered.
                    // This is not definitive proof of organic traffic.
                    self.state = .noMatch
                    return
                }

                guard HostAppDependencies.isConfigured,
                      let store =
                          HostAppDependencies.transactionStore
                else {
                    self.state = .retryableFailure
                    return
                }

                self.activeRecord = record

                guard store.save(record) else {
                    // Do not claim a durable pending record
                    // when persistence has failed.
                    self.state = .retryableFailure
                    return
                }

                self.state = .received
                self.processRecord(record)
            }
        })
    }

    private func parseAndSanitizeRawPayload(
        _ rawData: Any?
    ) -> PendingAttributionRecord? {

        guard let rawData = rawData else {
            return nil
        }

        var dictionary: [String: Any]?

        if let map = rawData as? [String: Any] {
            dictionary = map
        } else if let jsonString = rawData as? String,
                  jsonString.count <= 4096,
                  let data = jsonString.data(using: .utf8),
                  let parsed = try? JSONSerialization.jsonObject(
                      with: data
                  ) as? [String: Any] {
            dictionary = parsed
        }

        guard let payload = dictionary else {
            return nil
        }

        let pattern = "^[A-Za-z0-9_.-]{1,64}$"

        func field(_ key: String) -> String? {
            guard let value = payload[key] as? String,
                  value.range(
                    of: pattern,
                    options: .regularExpression
                  ) != nil
            else {
                return nil
            }

            return value
        }

        let now = Date().timeIntervalSince1970

        let record = PendingAttributionRecord(
            utmSource: field("utm_source"),
            utmMedium: field("utm_medium"),
            utmCampaign: field("utm_campaign"),
            inviterId: field("inviter_id"),
            promoCode: field("promo_code"),
            idempotencyKey: UUID().uuidString,
            createdAt: now,
            expiresAt: now + transactionTTL
        )

        return record.isValid ? record : nil
    }

    private func processRecord(
        _ record: PendingAttributionRecord
    ) {
        guard record.isValid,
              let processor =
                  HostAppDependencies.parameterProcessor
        else {
            state = .retryableFailure
            return
        }

        guard !processingInFlight else {
            return
        }

        processingInFlight = true

        // The host processor must confirm the required
        // attribution and reward outcomes independently.
        processor.process(record: record) {
            [weak self] outcome in

            DispatchQueue.main.async {
                guard let self = self,
                      self.activeRecord?.idempotencyKey ==
                          record.idempotencyKey
                else {
                    return
                }

                self.processingInFlight = false

                switch outcome {
                case .completed:
                    self.finalizeRecord(
                        record,
                        terminalState: .applied
                    )

                case .rejected:
                    self.finalizeRecord(
                        record,
                        terminalState: .rejected
                    )

                case .retryableFailure:
                    self.state = .retryableFailure
                }
            }
        }
    }

    private func finalizeRecord(
        _ record: PendingAttributionRecord,
        terminalState: ParamFetchState
    ) {
        guard activeRecord?.idempotencyKey ==
                  record.idempotencyKey,
              let store =
                  HostAppDependencies.transactionStore
        else {
            state = .retryableFailure
            return
        }

        // The host store must coordinate durable completion
        // and cleanup for the application's reliability needs.
        guard store.clear() else {
            state = .retryableFailure
            return
        }

        activeRecord = nil
        state = terminalState

        print(
            "OpoInstall: Install parameter processing resolved"
        )
    }
}

iOS उदाहरण एक डिफ़ॉल्ट UserDefaults-समर्थित लंबित लेनदेन स्टोर या एक टेलीमेट्री क्लाइंट प्रदान नहीं करता है जो स्वचालित रूप से सफलता की रिपोर्ट करता है.

होस्ट एप्लिकेशन को अपनी सुरक्षा, एनालिटिक्स और खाता प्रबंधन आवश्यकताओं के लिए उपयुक्त एक भंडारण कार्यान्वयन और एक पैरामीटर प्रोसेसर प्रदान करना चाहिए।

जहां एप्लिकेशन रिवॉर्ड-युक्त मानों को संसाधित करता है, प्रोसेसर को सर्वर-साइड प्राधिकरण समाप्त होने से पहले .completed नहीं लौटाना चाहिए.

जहां पेलोड में केवल मार्केटिंग डेटा शामिल है, पूर्णता को एप्लिकेशन की परिभाषित एनालिटिक्स स्वीकृति या विश्वसनीय कतारबद्ध आवश्यकता को प्रतिबिंबित करना चाहिए.

मिश्रित रिकॉर्ड के लिए, प्रोसेसर को प्रत्येक चैनल के लिए अनसुलझे कार्य को संरक्षित करना चाहिए और यह सुनिश्चित करना चाहिए कि पुराने कॉलबैक किसी भिन्न लेनदेन को अंतिम रूप न दें.

प्रतिनिधि कोड जानबूझकर एक पूर्ण रिट्राय शेड्यूलर और टिकाऊ मल्टी-चैनल लेनदेन जर्नल को छोड़ देता है। वे चिंताएं होस्ट एप्लिकेशन कार्यान्वयन में आती हैं और उनका परीक्षण उसके वास्तविक जीवनचक्र और बैकएंड के खिलाफ किया जाना चाहिए.

उत्पादन एकीकरण सीमाएं और सत्यापन चेकलिस्ट

किसी भी मोबाइल उदाहरण को तैनात करने से पहले, इंजीनियरिंग टीमों को निम्नलिखित शर्तों को सत्यापित करना चाहिए.

एकीकरण सीमा आवश्यक उत्पादन सत्यापन
वेब SDK तैनात रिलीज़ के लिए CDN स्रोत, कंस्ट्रक्टर कॉन्फ़िगरेशन, डाउनलोड विधि, और एसिंक्रोनस विफलता व्यवहार की पुष्टि करें।
नेटिव SDK सटीक Android AAR या iOS फ्रेमवर्क के खिलाफ पैकेज/मॉड्यूल नाम, इनिशियलाइज़ेशन आवश्यकताएं, कॉलबैक हस्ताक्षर, और पेलोड प्रकारों की पुष्टि करें।
इनपुट स्कीमा समर्थित पैरामीटर नाम, मान लंबाई, वर्ण नियम, और खराब या डुप्लिकेट कुंजियों के हैंडलिंग की पुष्टि करें।
संरक्षित भंडारण उपयुक्त सुरक्षा, समाप्ति, और त्रुटि रिपोर्टिंग के साथ एक एप्लिकेशन-प्रदान किया गया भंडारण कार्यान्वयन का उपयोग करें।
मार्केटिंग टेलीमेट्री पुष्टि करें कि सफल पूर्णता का अर्थ है कि एक एनालिटिक्स इवेंट को मज़बूती से स्वीकार किया गया है या टिकाऊ रूप से कतारबद्ध किया गया है, न कि केवल लॉग किया गया है।
रिवॉर्ड प्राधिकरण प्रमाणित एप्लिकेशन बैकएंड सत्यापन का उपयोग करें; क्लाइंट-प्रदान किए गए पैरामीटर्स के आधार पर कभी भी इनाम न दें।
मिश्रित पेलोड जब तक प्रत्येक आवश्यक परिणाम हल नहीं हो जाता तब तक स्वतंत्र रूप से लंबित एट्रिब्यूशन और रिवॉर्ड कार्य को संरक्षित करें।
आइडम्पोटेंसी पुनः प्रयास के दौरान स्थिर लेनदेन पहचान बनाए रखें और सर्वर पर रिवॉर्ड विशिष्टता लागू करें।
रिलीज़ बिल्ड Android मिनीफाइड बिल्ड और वास्तविक SDK आर्टिफैक्ट्स के साथ iOS बिल्ड को सत्यापित करें।
गोपनीयता समीक्षा प्लेटफॉर्म और नियामक आवश्यकताओं के खिलाफ SDK के वास्तविक डेटा संग्रह और मैचिंग व्यवहार को सत्यापित करें।

ये एकीकरण स्वीकृति मानदंड हैं, न कि ये दावे कि संदर्भ कोड या किसी विशेष SDK रिलीज़ ने पहले ही उत्पादन परीक्षण पास कर लिया है।

पैरामीटर पासिंग रणनीति तुलना मैट्रिक्स

पैरामीटर रेस्टोरेशन रणनीतियों का पद्धतिगत विश्लेषण

मोबाइल अधिग्रहण प्रणालियाँ वेब विज़िट और नेटिव एप्लिकेशन के बीच रेफरल और एट्रिब्यूशन संदर्भ को संरक्षित करने के लिए अलग-अलग दृष्टिकोणों का उपयोग करती हैं।

उपयुक्त दृष्टिकोण लक्ष्य प्लेटफॉर्म, आवश्यक पैरामीटर प्रकार, स्वीकार्य उपयोगकर्ता घर्षण, डेटा संवेदनशीलता, और उपलब्ध प्लेटफॉर्म तंत्र पर निर्भर करता है।

पैरामीटर रणनीति रेस्टोरेशन कवरेज उपयोगकर्ता घर्षण गोपनीयता / नीति संबंधी विचार बैकएंड प्राधिकरण और आइडम्पोटेंसी आवश्यक
मैन्युअल प्रोमो कोड प्रविष्टि उपयोगकर्ता भागीदारी और कोड उपलब्धता पर निर्भर करता है। उच्च; उपयोगकर्ता मैन्युअल रूप से कोड दर्ज करते हैं। कोड प्रविष्टि के लिए डिवाइस मैचिंग की आवश्यकता नहीं है, लेकिन सामान्य डेटा सुरक्षा नियम अभी भी लागू होते हैं। हां, रिवॉर्ड मोचन के लिए।
Google Play इंस्टॉल रेफरर समर्थित Android प्रवाह पर Google Play इंस्टॉलेशन। सफलतापूर्वक लागू होने पर न्यूनतम। आधिकारिक स्टोर-समर्थित परिवहन; डाउनस्ट्रीम प्रसंस्करण और डेटा उपयोग के लिए अभी भी समीक्षा की आवश्यकता है। हां, जब रेफरर मान रिवॉर्ड ट्रिगर कर सकते हैं।
OpoInstall पैरामीटर रेस्टोरेशन तैनात SDK व्यवहार, प्रवेश पथ, प्लेटफॉर्म, और अनुमत मैचिंग तंत्र पर निर्भर करता है। रेस्टोरेशन सफल होने पर आमतौर पर न्यूनतम। SDK डेटा प्रथाओं, अनुमतियों, और प्लेटफॉर्म नियमों के मूल्यांकन की आवश्यकता है। हां, रिवॉर्ड-युक्त पैरामीटर्स के लिए।

सटीकता, गोपनीयता अनुपालन, उपयोगकर्ता घर्षण, और सुरक्षा सीमाओं का मूल्यांकन

मैन्युअल प्रोमो कोड प्रविष्टि के बारे में तकनीकी रूप से सोचना आसान है लेकिन यह उपयोगकर्ता घर्षण पैदा कर सकता है।

Google Play इंस्टॉल रेफरर एक नेटिव, स्टोर-समर्थित Android रेफरल चैनल प्रदान करता है।

एक थर्ड-पार्टी पैरामीटर रेस्टोरेशन SDK योग्य आस्थगित संदर्भ के लिए एक एप्लिकेशन-स्तरीय एकीकरण परत प्रदान कर सकता है। हालांकि, इसके वास्तविक डिलीवरी कवरेज, तकनीकी तंत्र, और गोपनीयता विशेषताओं का मूल्यांकन तैनात रिलीज़ का उपयोग करके किया जाना चाहिए।

रेस्टोरेशन विधि चाहे जो भी हो, एप्लिकेशन को पैरामीटर प्राप्त करने और एक व्यावसायिक कार्रवाई को अधिकृत करने के बीच अंतर करना चाहिए।

पैरामीटर रेस्टोरेशन, स्टेट मैनेजमेंट, और SDK एकीकरण त्रुटियों का निवारण

क्लाइंट-साइड स्थिति संक्रमण का प्रबंधन: नो-मैच, रिट्राय, और टर्मिनल परिणामों को संभालना

मिश्रित एट्रिब्यूशन और रिवॉर्ड पेलोड को सफाई से पहले स्वतंत्र पूर्णता स्थितियों की आवश्यकता होती है।

एक पैरामीटर रेस्टोरेशन वर्कफ़्लो को सात तार्किक स्थितियों का उपयोग करके वर्णित किया जा सकता है:

स्थिति अर्थ
NOT_STARTED कोई पुनर्प्राप्ति प्रयास शुरू नहीं हुआ है।
FETCHING एप्लिकेशन इंस्टॉलेशन पैरामीटर्स का अनुरोध कर रहा है।
RECEIVED एक उम्मीदवार पेलोड प्राप्त हुआ है और प्रसंस्करण के लिए स्वीकार किया गया है।
APPLIED होस्ट प्रोसेसर रिपोर्ट करता है कि इस रिकॉर्ड के लिए सभी आवश्यक सफल परिणाम पूरे हो गए हैं।
REJECTED होस्ट प्रोसेसर एक परिभाषित टर्मिनल अस्वीकृति की रिपोर्ट करता है।
NO_MATCH पुनर्प्राप्ति प्रयास से योग्य कस्टम पैरामीटर्स उत्पन्न नहीं हुए।
RETRYABLE_FAILURE वर्कफ़्लो वर्तमान में जारी नहीं रह सकता है और इसे एक नियंत्रित नीति के तहत फिर से आजमाया जा सकता है।

ये स्थितियां एप्लिकेशन-स्तरीय परिणामों का वर्णन करती हैं। वे एनालिटिक्स, रिवॉर्ड्स, स्टोरेज और रिट्राय के लिए होस्ट एप्लिकेशन के टिकाऊ समन्वय को प्रतिस्थापित नहीं करती हैं।

विशेष रूप से, एक केवल-मार्केटिंग रिकॉर्ड रिवॉर्ड प्राधिकरण के बिना पूरा हो सकता है, जबकि एक रिवॉर्ड-युक्त रिकॉर्ड को उपयुक्त सर्वर प्रतिक्रिया प्राप्त करनी चाहिए।

एक NO_MATCH परिणाम को इस बात का निश्चित प्रमाण नहीं माना जाना चाहिए कि इंस्टॉलेशन ऑर्गेनिक था।

पैरामीटर अनुरोध टाइमआउट और नेटवर्क देरी को शालीनता से हल करना

पैरामीटर रेस्टोरेशन कनेक्टिविटी, कॉलबैक टाइमिंग, ऐप स्टार्टअप ऑर्डर, या अनुपलब्ध बैकएंड सेवाओं से प्रभावित हो सकता है।

एप्लिकेशन को चाहिए:

  • नेटवर्क कार्य को एसिंक्रोनस रखें।
  • इंस्टॉलेशन पैरामीटर पुनर्प्राप्ति के दौरान मुख्य उपयोगकर्ता इंटरफ़ेस को अवरुद्ध करने से बचें।
  • एक अनुपलब्ध SDK मैनेजर को खाली पैरामीटर परिणाम से अलग करें।
  • स्थानीय भंडारण त्रुटियों को प्रसंस्करण विफलताओं के रूप में मानें, न कि इस पुष्टि के रूप में कि कोई रिकॉर्ड मौजूद नहीं है।
  • हर फॉरग्राउंड संक्रमण पर बार-बार अनुरोध जारी करने के बजाय एक सीमित एप्लिकेशन नीति के अनुसार पुनः प्रयास करें।
  • जब किसी ऑपरेशन को फिर से आजमाने की आवश्यकता हो तो एक मौजूदा लंबित रिकॉर्ड को संरक्षित करें।

कोई भी कार्यान्वयन जो स्वचालित रूप से पुनः प्रयास करता है, उसे ओवरलैपिंग अनुरोधों को रोकना चाहिए और प्रतिस्थापित लेनदेन से संबंधित कॉलबैक को अस्वीकार करना चाहिए।

एप्लिकेशन ओवरराइट इंस्टॉलेशन और पुराने पैरामीटर बफ़र्स का प्रबंधन

पैरामीटर रेस्टोरेशन आमतौर पर एक योग्य इंस्टॉल के बाद पहले लॉन्च को लक्षित करता है, लेकिन एप्लिकेशन अपग्रेड और बार-बार लॉन्च पहले से संग्रहीत स्थानीय स्थिति को उजागर कर सकते हैं।

इंजीनियरिंग टीमों को यह परिभाषित करना चाहिए कि रेस्टोरेशन प्रयास कब योग्य है, पहले से उपभोग किए गए रिकॉर्ड की पहचान कैसे की जाती है, और लंबित डेटा कैसे समाप्त होता है।

रिवॉर्ड-युक्त पैरामीटर्स के लिए, सर्वर-साइड आइडम्पोटेंसी आवश्यक है। एक क्लाइंट-साइड फ़्लैग डुप्लिकेट रिवॉर्ड्स के खिलाफ पर्याप्त सुरक्षा नहीं है।

जब एप्लिकेशन स्थानीय रूप से लंबित लेनदेन को बनाए रखता है, तो उसे रिकॉर्ड को तभी हटाना चाहिए जब उसके आवश्यक प्रसंस्करण परिणाम टिकाऊ रूप से हल हो गए हों।

Android मल्टी-प्रोसेस पुनः-इनिशियलाइज़ेशन समस्याओं को रोकना

कई प्रक्रियाओं वाले Android एप्लिकेशन Application.onCreate() को एक से अधिक बार निष्पादित कर सकते हैं।

यदि नेटिव SDK केवल प्राथमिक एप्लिकेशन प्रक्रिया में इनिशियलाइज़ होने के लिए है, तो डेवलपर्स को इनिशियलाइज़ करने से पहले वर्तमान प्रक्रिया की जांच करनी चाहिए।

Android नमूना एक प्रक्रिया-नाम तुलना रणनीति प्रदर्शित करता है। उत्पादन एप्लिकेशन को समर्थित Android संस्करणों और प्रक्रिया आर्किटेक्चर के खिलाफ दृष्टिकोण की जांच करनी चाहिए।

क्लाइंट कॉलबैक हस्ताक्षर बेमेल और कोड श्रिंकर अस्पष्टीकरण नियमों को डीबग करना

एक थर्ड-पार्टी SDK के पैकेज नाम, कॉलबैक इंटरफ़ेस, और क्लास घोषणाएं रिलीज़ के बीच भिन्न हो सकती हैं।

जब एकीकरण विफल हो जाता है, तो डेवलपर्स को तैनात SDK को सत्यापित करना चाहिए, न कि यह मान लेना चाहिए कि उदाहरण इंटरफ़ेस अपरिवर्तित रहते हैं।

Android रिलीज़ बिल्ड के लिए:

  • सटीक SDK आर्टिफैक्ट के साथ प्रदान किए गए उपभोक्ता R8 / ProGuard नियमों को प्राथमिकता दें।
  • सबूत के बिना व्यापक पैकेज-व्यापी -keep या -dontwarn नियमों से बचें।
  • संकीर्ण पूरक नियम जोड़ने से पहले वास्तविक प्रतिबिंब आवश्यकताओं का निरीक्षण करें।
  • मिनीफाइड रिलीज़ कॉन्फ़िगरेशन में इंस्टॉलेशन पैरामीटर कॉलबैक का परीक्षण करें।

इस गाइड में कोड एक प्रतिनिधि एकीकरण है और इसे संबंधित बिल्ड और रनटाइम सबूत के बिना रिलीज़-सत्यापित के रूप में वर्णित नहीं किया जाना चाहिए।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

जब कोई उपयोगकर्ता ऐप स्टोर के माध्यम से ऐप इंस्टॉल करता है तो ट्रैकिंग पैरामीटर्स कैसे बने रहते हैं?
ट्रैकिंग पैरामीटर्स आस्थगित (deferred) पैरामीटर रेस्टोरेशन पाइपलाइन के माध्यम से बने रहते हैं। जब कोई उपयोगकर्ता वेब लैंडिंग पेज के साथ इंटरैक्ट करता है, तो OpoInstall वेब JS SDK क्वेरी पैरामीटर्स को पैकेज करता है और उन्हें एट्रिब्यूशन बैकएंड पर प्रसारित करता है। जब उपयोगकर्ता पहली बार नया इंस्टॉल किया गया एप्लिकेशन लॉन्च करता है, तो नेटिव OpoInstall SDK बैकएंड या Play Store API को क्वेरी करता है, सेशन का मिलान करता है और कस्टम क्वेरी पैरामीटर्स को ऐप तक पहुँचाता है।
iOS और Android पर क्लिपबोर्ड पेलोड पर कौन से गोपनीयता प्रतिबंध लागू होते हैं?
iOS 14 और बाद के संस्करणों पर, एप्लिकेशन के बीच सामान्य पेस्टबोर्ड तक पहुँचने से सिस्टम नोटिफिकेशन बैनर ट्रिगर हो सकता है, और iOS 16 में `UIPasteControl` जैसे नियंत्रणों के माध्यम से शुरू न होने तक प्रोग्रामेटिक रीड्स के लिए पेस्ट अनुमति प्रॉम्प्ट शुरू किए जाते हैं। Android 10 और बाद के संस्करणों पर, क्लिपबोर्ड एक्सेस केवल फॉरग्राउंड एप्लिकेशन तक सीमित है, और जब सामग्री कॉपी की जाती है तो Android 13 सिस्टम UI पुष्टिकरण प्रदान करता है। नतीजतन, क्लिपबोर्ड पेलोड को एक अबाधित प्राथमिक चैनल के बजाय एक वैकल्पिक, गोपनीयता-संवेदनशील परिवहन संकेत के रूप में माना जाना चाहिए।
क्या ट्रैकिंग पैरामीटर्स डायनामिक इन-ऐप रूटिंग के लिए नेस्टेड JSON पेलोड ले जा सकते हैं?
हालांकि अंतर्निहित नेटवर्क प्रोटोकॉल स्ट्रिंगिफाइड JSON पेलोड को परिवहन कर सकते हैं, उत्पादन सुरक्षा आर्किटेक्चर—जिसमें इस गाइड में संदर्भ कार्यान्वयन शामिल है—स्क्रिप्ट इंजेक्शन और मेमोरी सीमा जोखिमों को कम करने के लिए सख्त अलाउलिस्टेड स्केलर स्कीमा (जैसे, 64 वर्णों तक के अल्फ़ान्यूमेरिक स्ट्रिंग्स और अभियान टोकन) को लागू करते हैं। यदि जटिल इन-ऐप रूटिंग की आवश्यकता है, तो एप्लिकेशन को एक अपारदर्शी रूट पहचानकर्ता पास करना चाहिए और क्लाइंट पर सीधे असत्यापित नेस्टेड JSON संरचनाओं को पार्स करने के बजाय विश्वसनीय बैकएंड कॉन्फ़िगरेशन से समृद्ध नेविगेशन पथों को सुरक्षित रूप से हल करना चाहिए।

सारांश और निर्णय ढांचा

वेब क्लिक को मोबाइल ऐप स्टोर इंस्टॉल के साथ जोड़ने के लिए एक पैरामीटर रेस्टोरेशन दृष्टिकोण की आवश्यकता होती है जो ब्राउज़र, ऐप स्टोर और नेटिव एप्लिकेशन के बीच तकनीकी सीमाओं का सम्मान करता है।

Android के लिए, Google Play इंस्टॉल रेफरर API समर्थित इंस्टॉलेशन प्रवाह के लिए एक आधिकारिक रेफरल तंत्र प्रदान करता है। iOS के लिए, मनमाने वेब पैरामीटर्स ऐप स्टोर के माध्यम से स्वचालित रूप से वितरित नहीं किए जाते हैं, इसलिए आस्थगित रेस्टोरेशन के लिए एक स्वतंत्र रूप से सत्यापित, गोपनीयता-जागरूक दृष्टिकोण की आवश्यकता होती है।

एक व्यावहारिक OpoInstall एकीकरण अलाउलिस्टेड लैंडिंग-पेज पैरामीटर्स को कैप्चर कर सकता है और नेटिव SDK के माध्यम से योग्य संदर्भ का अनुरोध कर सकता है। फिर एप्लिकेशन को मार्केटिंग एट्रिब्यूशन, नेविगेशन, या प्रचार वर्कफ़्लो के लिए उपयोग करने से पहले पुनर्प्राप्त डेटा को सामान्यीकृत और सत्यापित करना चाहिए।

प्रमुख इंजीनियरिंग अंतर पैरामीटर रेस्टोरेशन और एप्लिकेशन-साइड प्रोसेसिंग के बीच है। एक पैरामीटर को पुनर्प्राप्त करने की गारंटी एनालिटिक्स डिलीवरी, रिवॉर्ड पात्रता, या सफल प्राधिकरण की नहीं होती है।

संदर्भ कोड SDK एकीकरण सीमाओं और एप्लिकेशन-परिभाषित अनुबंधों को प्रदर्शित करता है। उत्पादन टीमों को अपना स्वयं का संरक्षित भंडारण, विश्वसनीय एनालिटिक्स हैंडलिंग, सर्वर-साइड पात्रता सत्यापन, और जीवनचक्र समन्वय प्रदान करना चाहिए।

विक्रेता एकीकरण आवश्यकताओं का पता लगाने के लिए, OpoInstall SDK दस्तावेज़ीकरण या OpoInstall डेवलपर पंजीकरण पृष्ठ देखें।

संबंधित सामग्री

अवधारणाएं: ऐप पैरामीटर इंस्टॉलेशन, Google Play इंस्टॉल रेफरर, आस्थगित पैरामीटर रेस्टोरेशन, एट्रिब्यूशन टेलीमेट्री, सर्वर प्राधिकरण सीमा।

प्रौद्योगिकियां: वेब JS SDK, नेटिव मोबाइल SDK, URL क्वेरी पैरामीटर्स, Android कीस्टोर, iOS कीचेन सेवाएँ।

मानक: IETF RFC 3986 URI सिंटैक्स, OWASP मोबाइल एप्लिकेशन सुरक्षा सत्यापन मानक, W3C क्लिपबोर्ड API और इवेंट्स।

API: OpoInstall नेटिव इंस्टॉलेशन पैरामीटर API, Google Play इंस्टॉल रेफरर API, Apple UIPasteboard API, Android क्लिपबोर्ड API।

आधिकारिक दस्तावेज़ीकरण और संदर्भ:

Share this article

Keep Discovering

मेटा (Meta) म्यूज (Muse) की लाभप्रदता का रास्ता कैसे तलाश रहा है? मोबाइल ग्रोथ टीमों के लिए इसके क्या सबक हैं

मेटा (Meta) म्यूज (Muse) की लाभप्रदता का रास्ता कैसे तलाश रहा है? मोबाइल ग्रोथ टीमों के लिए इसके क्या सबक हैं

जैसे-जैसे उपभोक्ता एआई का विस्तार हो रहा है, मेटा (Meta) म्यूज की लाभप्रदता का मार्ग देख रहा है। जानें कि यूजर रिटेंशन, एजेंटिक शॉपिंग और मोबाइल एट्रिब्यूशन यूनिट इकोनॉमिक्स को कैसे आकार देते हैं।

ऐप्पल ने iOS 27.2 RC जारी किया? सिरी AI अपग्रेड का क्या मतलब है

ऐप्पल ने iOS 27.2 RC जारी किया? सिरी AI अपग्रेड का क्या मतलब है

ऐप्पल ने विस्तृत सिरी AI भाषाओं और यूरोपीय संघ ATT फ्रेमवर्क अपडेट के साथ iOS 27.2 RC जारी किया है। डेवलपर API परिवर्तनों, गोपनीयता नियमों और SDK दिशानिर्देशों का पता लगाएं।

क्या Apple को अधिक प्रीमियम गेम्स मिल रहे हैं? पब्लिशर्स को इससे क्या लाभ होता है

क्या Apple को अधिक प्रीमियम गेम्स मिल रहे हैं? पब्लिशर्स को इससे क्या लाभ होता है

Apple ने नए App Store नेतृत्व के तहत प्रीमियम मोबाइल गेम्स में वृद्धि की रिपोर्ट दी है। पेड डाउनलोड और Apple Arcade के समानांतर व्यावसायिक मॉडलों का अन्वेषण करें।