2014-11-19 4 views
18

मेरे सवाल का प्रभावी ढंग से पूछना करने के लिए, की पहली सटीक परिदृश्य मैं का सामना करना पड़ रहा है पर विचार करें:मेजबान ऐप और एक्सटेंशन दोनों द्वारा उपयोग किए गए साझा ऐप कंटेनर में कोर डेटा स्टोर में अद्वितीय प्रविष्टियों की गारंटी कैसे दे सकता हूं?

सामान्य सेटअप

  • एक मेजबान iOS 8 अनुप्रयोग।
  • होस्ट ऐप के साथ एक या अधिक आईओएस 8 एक्सटेंशन (वॉचकिट, शेयर इत्यादि) बंडल किया गया।
  • होस्ट ऐप और सभी एक्सटेंशन साझा ऐप समूह कंटेनर में एक ही कोर डेटा SQLite स्टोर साझा करते हैं।
  • प्रत्येक ऐप/एक्सटेंशन का अपना एनएसपीर्सिस्टेंटस्टोरकॉर्डिनेटर और एनएसएमएनेज ऑब्जेक्ट कॉन्टेक्स्ट होता है।
  • प्रत्येक निरंतर स्टोर समन्वयक एक सतत स्टोर का उपयोग करता है जो समूह कंटेनर में अन्य सभी स्थिर स्टोर्स के समान SQLite संसाधन साझा करता है।
  • ऐप और सभी एक्सटेंशन इंटरनेट पर रिमोट एपीआई संसाधन से सामग्री को सिंक करने के लिए एक सामान्य कोडबेस का उपयोग करते हैं। समस्या को

    1. उपयोगकर्ता प्रमुख घटनाओं की

अनुक्रम मेजबान ऐप्लिकेशन को लॉन्च। यह रिमोट एपीआई संसाधन से डेटा लाने शुरू होता है। कोर डेटा मॉडल ऑब्जेक्ट्स एपीआई प्रतिक्रिया और मेजबान ऐप के प्रबंधित ऑब्जेक्ट संदर्भ में "अपरिवर्तित" के आधार पर बनाए जाते हैं। प्रत्येक एपीआई इकाई में एक अद्वितीय आईडी है जो इसे दूरस्थ API बैकएंड में पहचानती है। "अपरिवर्तित" से मेरा मतलब है कि प्रत्येक एपीआई इकाई के लिए, होस्ट ऐप केवल कोर डेटा में एक नई प्रविष्टि बनाता है यदि किसी दिए गए अद्वितीय आईडी के लिए मौजूदा प्रविष्टि नहीं मिल पाती है।

  • इस बीच, उपयोगकर्ता भी मेजबान एप्लिकेशन की एक एक्सटेंशन में लॉन्च किया गया। यह भी एक ही रिमोट एपीआई से कुछ प्रकार का fetch प्रदर्शन करता है। यह API प्रतिक्रियाओं को पार्स करते समय "अपरर्ट" करने का भी प्रयास करता है।

  • समस्या: क्या होता है यदि मेजबान ऐप और एक्सटेंशन दोनों एक ही समय में एक ही एपीआई इकाई के लिए कोर डेटा प्रविष्टि को अपरिवर्तित करने का प्रयास करते हैं? इस तरीके के बारे में आ सकता है देखने के लिए, चलो एक Upsert के लिए घटनाओं के अनुक्रम को देखो:

  • कोर डाटा Upsert अनुक्रम:

    1. एपीआई पार्स कोड दिए गए एपीआई के लिए uniqueID पार्स इकाई।
    2. पार्सर कि एक विधेय जहां uniqueID पार्स uniqueID के बराबर है मेल खाने वाले किसी प्रविष्टि के लिए एक कोर डेटा लाने प्रदर्शन करती है।
    3. तो किसी मौजूदा प्रविष्टि नहीं पाया जाता है, पार्सर इस एपीआई इकाई के लिए एक नया कोर डेटा प्रविष्टि, पार्स uniqueID करने के लिए सेट के अपने uniqueID विशेषता सम्मिलित करता है।
    4. पार्सर प्रबंधित वस्तु संदर्भ है, जो SQLite समर्थन की दुकान करने के लिए नीचे नई प्रविष्टि डेटा धक्का बचाता है।
    5. विस्तार में

    समस्या

    के होस्ट ही ऐप्लिकेशन और एक्सटेंशन को स्वतंत्र रूप एक ही समय में एक ही एपीआई इकाई के लिए एक API जवाब पार्स कर रहे हैं मान लेते हैं। यदि मेजबान ऐप और एक्सटेंशन दोनों चरण 3 तक पहुंचने से पहले चरण 4 तक पहुंच गए हैं, तो वे दोनों एक ही अद्वितीय आईडी के लिए एक नई कोर डेटा प्रविष्टि डालने का प्रयास करेंगे। जब वे चरण 4 तक पहुंचते हैं और अपने संबंधित प्रबंधित ऑब्जेक्ट संदर्भों पर save: पर कॉल करते हैं, तो कोर डेटा खुशी से डुप्लिकेट प्रविष्टियां बनाएगा।

    जहां तक ​​मुझे पता है, कोर डेटा के पास एक विशेषता को अद्वितीय के रूप में चिह्नित करने का कोई तरीका नहीं है। मुझे SQLite INSERT OR IGNORE + UPDATE combo. के समतुल्य कोर डेटा की आवश्यकता है। अन्यथा मुझे लगातार स्टोर की SQLite बैकिंग स्टोर को "लॉक" करने का एक तरीका चाहिए, जो परेशानी के लिए नुस्खा की तरह लगता है।

    क्या आईओएस 8 एक्सटेंशन द्वारा पेश की गई उपन्यास समस्या के बारे में कोई ज्ञात दृष्टिकोण है?

    +0

    मेजबान पृष्ठभूमि मोड में जाने पर GET अनुरोधों को रद्द/रोक क्यों नहीं देते? – 3lvis

    +0

    कोर डेटा अप्सर्ट अनुक्रम के चरण 2 में इसके लिए मुझे डुप्लिकेट प्रविष्टियां मिल रही हैं, इसके लिए कोर एक से अधिक परिणाम होने पर मैं अतिरिक्त प्रविष्टियां हटा देता हूं। https://github.com/NSElvis/NSManagedObject-ANDYMapChanges/blob/master/Source/NSManagedObject%2BANDYMapChanges.m#L52 – 3lvis

    उत्तर

    10

    क्या आईओएस 8 एक्सटेंशन द्वारा पेश की गई उपन्यास समस्या के बारे में कोई ज्ञात दृष्टिकोण है?

    हां, यह वही दृष्टिकोण है जो कोर डेटा के साथ iCloud का उपयोग करते समय लागू होता है: डुप्लिकेट होने दें, लेकिन फिर जाएं और उन्हें साफ़ करें। दोनों परिस्थितियां डुप्लिकेट प्रविष्टियां बनाने का जोखिम चलाती हैं, और उन्हें रोकने के लिए कोई विश्वसनीय तरीका नहीं है। चूंकि आपके पास uniqueID कुंजी है, इसलिए आप जहां तक ​​चिंतित हैं, आप अच्छे आकार में हैं।

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

    ढूँढना डुप्लिकेट होगा कुछ की तरह:

    SELECT uniqueID, COUNT(uniqueID) FROM MyEntityName GROUP BY uniqueID; 
    

    आप शब्दकोशों की एक सरणी मिलता है, जिनमें से प्रत्येक:

    NSError *error = nil; 
    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init]; 
    [moc setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 
    
    NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:@"MyEntityName"]; 
    [fr setIncludesPendingChanges:NO]; 
    
    NSExpression *countExpr = [NSExpression expressionWithFormat:@"count:(uniqueID)"]; 
    NSExpressionDescription *countExprDesc = [[NSExpressionDescription alloc] init]; 
    [countExprDesc setName:@"count"]; 
    [countExprDesc setExpression:countExpr]; 
    [countExprDesc setExpressionResultType:NSInteger64AttributeType]; 
    
    NSAttributeDescription *uniqueIDAttr = [[[[[_psc managedObjectModel] entitiesByName] objectForKey:@"MyEntityName"] propertiesByName] objectForKey:@"uniqueID"]; 
    [fr setPropertiesToFetch:[NSArray arrayWithObjects:uniqueIDAttr, countExprDesc, nil]]; 
    [fr setPropertiesToGroupBy:[NSArray arrayWithObject:uniqueIDAttr]]; 
    
    [fr setResultType:NSDictionaryResultType]; 
    
    NSArray *countDictionaries = [moc executeFetchRequest:fr error:&error]; 
    

    यह काफी एसक्यूएल में कुछ इस तरह की कोर डाटा बराबर है uniqueID और मूल्य का उपयोग करने की संख्या की संख्या शामिल है। शब्दकोश के माध्यम से चलाएं और डुप्लिकेट के साथ उचित तरीके से निपटें।

    मैंने इसे a blog post में अधिक विस्तार से वर्णित किया। ऐप्पल से एक नमूना प्रोजेक्ट भी है जो साझाकोरडाटा नामक प्रक्रिया को प्रदर्शित करता है, लेकिन मेरा मानना ​​है कि यह केवल WWDC 2012 sample code bundle के हिस्से के रूप में उपलब्ध है। इस सम्मेलन में सत्र 227 में भी इसका वर्णन किया गया था।

    9

    ऐसा लगता है कि यह सबसे आसान तरीका है कि पहले कई लेखकों से बचें। क्यों न केवल अपने एक्सटेंशन को कैश किए गए डेटा से पूरी तरह से ड्राइव करें, और फिर अपने प्राथमिक आईओएस ऐप से केवल अपने डेटा स्टोर को अपडेट करें?

    +0

    यह अनुशंसित दृष्टिकोण है। – Dhawal

    संबंधित मुद्दे