2012-03-29 29 views
8

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

मेरा मुख्य तालिका निम्नलिखित गुणों के साथ एंट्री कहा जाता है:

NSInteger type; 
NSDate* timestamp; 
NSString* username; 
NSString* session; 
NSString* body; 

जहां 'प्रकार' हो सकता है:

1 - message 
2 - file transfer (which then 'body' represents a file name in the documents folder) 
3 - user joined 
4 - user left 

मेरा ऐप भी बहु उपयोगकर्ता बातचीत (इसलिए क्यों 'उपयोगकर्ता का समर्थन करता है '/' उपयोगकर्ता बाएं 'प्रकार में शामिल हो गए)। सभी संदेश एक ही वार्तालाप से संबंधित हैं (केवल बहु-चैट), एक वैध 'सत्र' संपत्ति होगी।

मेरे चैट इतिहास में, मेरी समस्या यह है कि ऐप्पल जैसे एसएमएस लोड में 'लोड लोड' को कैसे प्राप्त किया जाए: मैं उस इतिहास को दिखाने के लिए 'username=%@ AND session IS NULL' या 'session=%@' पर आधारित प्रश्न पूछूंगा और 50% टाइमस्टैम्प '। मैं फिर एक बटन "अधिक लोड" करना चाहता हूं जो अगले 50 संदेशों को लोड करेगा - मुझे यकीन नहीं है कि कोर डेटा के साथ इसे कैसे किया जाए।

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

धन्यवाद

उत्तर

14

"सभी participants.username =% @" किसी एप्लिकेशन को प्राप्त करने से

तो, सभी वार्तालापों, जिसमें एक विशेष उपयोगकर्ता भाग लिया, तो आप एक विधेय समान के साथ "प्रतिभागी" पर लाने की तरह कुछ कर सकता है पाने के लिए है कि बिल्कुल वही बात करता है, यहां मेरी अंतर्दृष्टि हैं।

सबसे पहले आपको कोडिंग से पहले कॉर्डेटा और मल्टीथ्रेडिंग बुद्धिमानी पर विचार करना चाहिए। अगर आपको उस पर मदद की ज़रूरत है तो मुझे बताएं।

मॉडल

आप CoreData में संस्थाओं, जो SQLite में तालिकाओं की तरह माना जा सकता है के साथ काम कर रहे हैं, लेकिन एक और अधिक सार तरीके से। इसके लिए आपको review Apple's documentation होना चाहिए।

हम आपके मामले में कम से कम तीन अलग-अलग इकाइयां पा सकते हैं: उपयोगकर्ता, वार्तालाप, और संदेश। (आखिरी के साथ सावधान रहें, मुझे एसएमएस फ्रेमवर्क आयात करते समय संदेश नामक इकाई के साथ कोई समस्या थी, आपको इकाई के नाम को उपसर्ग करने पर विचार करना चाहिए ..)

कोर्डटा के साथ एक मुद्दा यह है कि आप सीधे स्टोर नहीं कर सकते सरणी (कुछ अज्ञात प्रकार के साथ हो सकता है) लेकिन वैसे भी। तो दो समाधान अपने उपयोगकर्ताओं को स्टोर करने के लिए:

Conversation{ 
    messages<-->>Message.conversation 
    lastMessage<-->Message.whateverName 
    //optional 
    users<<-->>User.conversation 
} 

Message{ 
    conversation<<-->Conversation.messages 
    whatevername<-->Conversation.lastmessage // "whatever as it does not really matter" 
} 

User{ 
    conversations<<-->>Conversation.users 
} 
: या तो एक NSString .. जब वे comas और एक साधारण regex या विभाजन आप उपयोगकर्ताओं की संख्या दे देंगे से सीमांकित किया जाएगा

तो अपने मॉडल की तरह लग सकता है

वार्तालाप में संदेश और संदेश के साथ एक से अधिक संबंध होना चाहिए बातचीत के लिए एक-एक रिश्ते।

--EDIT

तुम सिर्फ संदेश अनुप्रयोग (या मेरे एप्लिकेशन) की तरह एक बातचीत का अंतिम संदेश प्रदर्शित करना चाहते हैं, तो आप संदेश के साथ एक रिश्ता जोड़ सकते हैं। यह डेटाबेस/coredata में संदेश दो बार संग्रहीत नहीं करेगा। दरअसल, आप एक कोर्डाटा ऑब्जेक्ट बनाते हैं (इस मामले में एक संदेश) और आप इसे एक वार्तालाप में जोड़ते हैं, अंदर क्या होता है कि वार्तालाप उस ऑब्जेक्ट के लिए कॉर्डेटा आईडी संग्रहीत करता है। इस संदेश (lastMessage) के लिए एक रिश्ते जोड़ना केवल एक और आईडी स्टोर करेगा, न कि कोई अन्य वस्तु।

संपादित

उपयोगकर्ता की --end थोड़ा अलग है क्योंकि वे (समूह वार्तालाप की वजह से) से अधिक वार्तालापों का हिस्सा हो सकता है यही कारण है कि आप एक बहुत-से-अनेक संबंध जहाज की जरूरत है।

आप जितनी चाहें उतनी विशेषताओं को जोड़ सकते हैं, लेकिन यह न्यूनतम आवश्यकता है!

  1. कार्यान्वयन
अपने कोड में तो

, अगर आप iMessage के व्यवहार की नकल करना चाहते हैं, यहाँ मैं क्या किया है:

पहले नियंत्रक, जहां आप सभी वार्तालाप देख सकते हैं में

: एक NSFetchedResultController का उपयोग करें। क्वेरी केवल इकाई वार्तालाप के बारे में होना चाहिए।

पंक्ति पर क्लिक करते समय, मैंने जो किया वह यह है कि नए दृश्य में वार्तालाप वस्तु और अन्य NSFtechedResultController है। मैं फिर केवल इकाई संदेश से पूछता हूं लेकिन भविष्यवाणी के साथ कि मैं केवल यह वार्तालाप चाहता हूं।

आप तरलता को देखने के लिए मेरे ऐप की जांच करना चाहते हैं, तो go to this link.

संपादित

  1. कोड स्निपेट बातचीत का अंतिम संदेश

खोजने के लिए सावधान: यह ऐसा करने का एक बेहतर तरीका खोजने से पहले एक अस्थायी उत्तर है (यानी जब प्राप्ति गुणों का उपयोग करते हैं)

NSFetchRequest * req = [[NSFetchRequest alloc] init]; 
[req setEntity:[NSEntityDescription entityForName:@"Message" inManagedObjectContext:context]]; 
[req setPredicate:[NSPredicate predicateWithFormat:@"conversation == %@", self]]; /* did that from a Conversation object.. */ 
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"sent_date" ascending:NO]; 
[req setSortDescriptors:[NSArray arrayWithObject:sort]]; 

[sort release]; 
NSError * error = nil; 
NSArray * messages = [context executeFetchRequest:req error:&error]; 
[req release]; 
if ([messages count] > 0) { /* sanity check */ 
    return [messages objectAtIndex:0]; 
} 
return nil; 

संपादित की --end

आशा इस मदद!

पियरे

+0

मैं आपके सुझाव के साथ गया, लेकिन वार्तालाप सूची पढ़ते समय - मुझे वहां दिखाने के लिए अंतिम संदेश कैसे मिलता है (जैसा कि आपने "संदेश" स्क्रीन में किया था)। धन्यवाद। –

+0

हाय गिलाद मैंने थोड़ा जवाब दिया। मूल रूप से, केवल अंतिम मैसेज या जो कुछ भी आप चाहते हैं उसे एक-से-एक संबंध जोड़ें। हर बार जब आप एक नया संदेश/delete_the_last_one प्राप्त करते हैं, तो बस अंतिम संदेश फ़ील्ड को अपडेट करें। यदि आप अतिरिक्त संबंध जोड़ने के प्रशंसक नहीं हैं, तो आप मुझे अंतिम संदेश खोजने के लिए प्रत्येक बातचीत के लिए NSFetchRequest में खोदने का अनुमान लगा सकते हैं, लेकिन यह बहुत खराब हो सकता है, प्रदर्शन के अनुसार। आशा है कि – Pierre

+0

धन्यवाद बहुत धन्यवाद पियरे - यही वह है जो मैंने अंततः किया था। संदेश हटाने पर मुझे थोड़ी सी समस्या है (मुझे अब नवीनतम संदेश मैन्युअल रूप से पहचानने और मेरी वार्तालाप वस्तु को अपडेट करने की आवश्यकता है), लेकिन कम से कम मुझे इतिहास ठीक से मिलता है। धन्यवाद!!! –

1

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

अगला, आपके "50 आइटम" मुद्दे के लिए, NSFetchRequest देखें। आप इसे कहां से शुरू कर सकते हैं (fetchOffset), और कितने आइटम लाने के लिए (fetchLimit)। आपके लिए अन्य विकल्प भी हैं। यदि आपकी कुल संख्या की संख्या अपेक्षाकृत छोटी है, तो आप केवल संपूर्ण सरणी प्राप्त कर सकते हैं (और केवल एक ही समय में गलती करें - fetchBatchSize देखें)।

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

संपादित

जब आप वार्तालाप वस्तु बनाते हैं, आप जो सभी उपयोगकर्ताओं है कि उस बातचीत में भाग लिया का एक सेट होगा "प्रतिभागियों" की तरह कुछ करने के लिए एक से-अनेक संबंध शामिल कर सकते हैं। उलटा "उपयोगकर्ता" में बहुत से रिश्ते भी होंगे जिसमें उपयोगकर्ता द्वारा किए गए सभी वार्तालापों में शामिल था (मुझे लगता है कि आपके डेटाबेस में एकाधिक उपयोगकर्ता हैं ???)।

+0

प्रश्न के दूसरे भाग के लिए: मुझे क्या करना कोशिश कर रहा हूँ सब वार्तालाप सूची (, उनमें से एक सूची दिखाने के लिए एक उपयोगकर्ता क्लिक कर सकते हैं और उसके बाद पूरी बातचीत को देखने के लिए विस्तार जहां) है । यह iMessage के समान है। मैं प्रत्येक अद्वितीय वार्तालाप का अंतिम संदेश दिखाना चाहता हूं। मैं उपयोगकर्ता नाम से समूह नहीं कर सकता क्योंकि उपयोगकर्ता दो बार दिखाई दे सकता है (एक बार एक चैट में और एक बार समूह चैट में) –

+0

आप सभी वार्तालापों का अंतिम संदेश दिखाना चाहते हैं, या सिर्फ वे लोग जिन्हें अंतिम उपयोगकर्ता अंतिम संदेश था ? क्षमा करें, मैं चैट क्लाइंट का उपयोग नहीं करता, इसलिए मैं समानता से परिचित नहीं हूं। –

+0

मान लीजिए कि मैंने उपयोगकर्ता ए (हमने 100 संदेशों का आदान-प्रदान किया) के साथ बातचीत की थी, और उपयोगकर्ता बी (50 संदेश) के साथ एक और वार्तालाप और उपयोगकर्ता ए/बी दोनों के साथ एक समूह चैट (10 संदेश): मैं 3 के साथ एक सूची प्रदर्शित करना चाहता हूं आइटम (ए, बी, ए/बी)। यदि आप पहली प्रविष्टि पर क्लिक करते हैं - आपको 100 संदेश इतिहास दिखाई देंगे, दूसरी प्रविष्टि पर क्लिक करने से 50 संदेश इतिहास दिखाए जाएंगे और तीसरे आइटम पर क्लिक करने से 10 संदेश दिखाए जाएंगे। मैं iMessage नकल करने के लिए देख रहा हूँ। –