2012-12-12 7 views
13

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

मैं -saveToURL:ofType:forSaveOperation:completionHandler: सहित कस्टम कोड का उपयोग करके लोडिंग और बचत को संभालता हूं। +autosavesInPlaceYES देता है।

मेरी समस्या यह है कि: कस्टम URL योजना वाले दस्तावेज़ स्टार्टअप पर पुनर्स्थापित नहीं किए जाते हैं। फ़ाइल यूआरएल योजना के साथ दस्तावेज हैं - फाइलों में सहेजे गए नियमित दस्तावेज, और शीर्षक रहित दस्तावेज़ जो स्वत: सहेजे गए हैं।

खुले सर्वर-आधारित दस्तावेज़ों को छोड़ने और ऐप छोड़ने के बाद, किसी भी NSDocument विधियों को पुनरारंभ करने के लिए नहीं कहा जाता है। विशेष रूप से, चार initializers में से कोई भी कहा जाता है:

  • -init
  • -initWithContentsOfURL: ofType: त्रुटि:
  • -initForURL: withContentsOfURL: ofType: त्रुटि:
  • -initWithType: त्रुटि:

NSDocumentController विधि -reopenDocumentForURL:withContentsOfURL:display:completionHandler: या तो नहीं कहा जाता है।

दस्तावेजों के पुनर्विक्रय राज्य कैसे और कब एन्कोड किए गए हैं? वे कब और कब डीकोड किए जाते हैं?

उत्तर

13

एनएसडी दस्तावेज़ -encodeRestorableStateWithCoder: में अपने शेष राज्य को एन्कोड करने के लिए ज़िम्मेदार है, और NSDocumentController दस्तावेज़ों के पुनर्मूल्यांकन राज्य को डीकोड करने और +restoreWindowWithIdentifier:state:completionHandler: में दस्तावेज़ों को फिर से खोलने के लिए ज़िम्मेदार है। NSDocumentRestoration.h में सहायक टिप्पणियों का संदर्भ लें।

जब NSDocument URL को एन्कोड करता है, तो यह NSURL के बुकमार्क विधियों का उपयोग करता प्रतीत होता है। समस्या यह है कि ये विधियां केवल फाइल-सिस्टम यूआरएल के साथ काम करती हैं। (यह संभव है कि गैर-फ़ाइल यूआरएल एन्कोड होंगे, लेकिन वे ठीक से डीकोड नहीं करेंगे।)

समस्या को ठीक करने के लिए, कस्टम योजना का उपयोग करने वाले NSDocument उदाहरणों के एन्कोडिंग को ओवरराइड करें, और इसी तरह, उन दस्तावेज़ों का डीकोडिंग।

NSDocument उपवर्ग:

- (void) encodeRestorableStateWithCoder:(NSCoder *) coder { 
    if ([self.fileURL.scheme isEqualToString:@"customscheme"]) 
     [coder encodeObject:self.fileURL forKey:@"MyDocumentAutoreopenURL"]; 
    else 
     [super encodeRestorableStateWithCoder:coder]; 
} 

NSDocumentController उपवर्ग:

+ (void) restoreWindowWithIdentifier:(NSString *) identifier 
           state:(NSCoder *) state 
        completionHandler:(void (^)(NSWindow *, NSError *)) completionHandler { 

    NSURL *autoreopenURL = [state decodeObjectForKey:@"MyDocumentAutoreopenURL"]; 
    if (autoreopenURL) { 
     [[self sharedDocumentController] 
     reopenDocumentForURL:autoreopenURL 
     withContentsOfURL:autoreopenURL 
     display:NO 
     completionHandler:^(NSDocument *document, BOOL documentWasAlreadyOpen, NSError *error) { 

      NSWindow *resultWindow = nil; 
      if (!documentWasAlreadyOpen) { 

       if (![[document windowControllers] count]) 
        [document makeWindowControllers]; 

       if (1 == document.windowControllers.count) 
        resultWindow = [[document.windowControllers objectAtIndex:0] window]; 
       else { 
        for (NSWindowController *wc in document.windowControllers) 
         if ([wc.window.identifier isEqual:identifier]) { 
          resultWindow = wc.window; 
          break; 
         } 
       } 
      } 
      completionHandler(resultWindow, error); 
     } 
     ]; 
    } else 
     [super restoreWindowWithIdentifier:identifier 
            state:state 
         completionHandler:completionHandler]; 
} 

व्यवहार या पूरा होने हैंडलर NSDocumentRestoration.h में से एप्पल के विधि टिप्पणी इस प्रकार है और मोटे तौर पर के रूप में ही किया जाना चाहिए super है।

4

विंडो स्थिति एन्कोडिंग NSWindow पर दो विधियों द्वारा सक्षम है। विंडो पर setRestorable: को कॉल करना इसे एक के रूप में चिह्नित किया जाता है जिसे सहेजा जा सकता है और फिर से लॉन्च किया जा सकता है, और फिर setRestorationClass: पर कॉल करने से आप एक कक्षा निर्दिष्ट कर सकते हैं जो सहेजी गई विंडो को पुनर्निर्मित करने में सक्षम होगी।

डिफ़ॉल्ट रूप से, ऐपकिट ऑब्जेक्ट्स द्वारा नियंत्रित विंडोज़ की बहाली कक्षा के रूप में NSDocumentController सेट करता है। NSWindowRestoration प्रोटोकॉल द्वारा परिभाषित विधि +restoreWindowWithIdentifier:state:completionHandler: को कॉल करके वास्तविक बहाली की जाती है। दस्तावेजों के लिए, NSDocumentController उस पद्धति को लागू करता है और NSDocument ऑब्जेक्ट को NSCoder उदाहरण में एन्कोड किए गए राज्य के आधार पर विधि में पारित करता है।

तो, सैद्धांतिक रूप से, यदि आप NSDocumentController को उपclass करना चाहते हैं और उस विधि को ओवरराइड करना चाहते हैं, तो आपको राज्य बहाली तंत्र द्वारा सहेजे गए दस्तावेज़ों को पुनर्स्थापित करने का अवसर मिलेगा। हालांकि, जहां तक ​​मुझे पता है, राज्य स्टोर करने के लिए NSDocumentController द्वारा उपयोग की जाने वाली कुंजियां कहीं भी दस्तावेज नहीं की गई हैं, इसलिए मुझे नहीं लगता कि NSDocumentController स्वयं स्टोर से सीधे पुनर्स्थापित करने का एक विश्वसनीय तरीका होगा।

इस का समर्थन करने के लिए, आप शायद दस्तावेज़ खुद के लिए पूरे राज्य एन्कोड करने के लिए, NSWindow पर -encodeRestorableStateWithCoder: को लागू करने से एन्कोड किया जा रहा खिड़की के लिए window:willEncodeRestorableState: प्रतिनिधि विधि लागू की आवश्यकता होगी, और/या। उन दोनों विधियों में आपको NSCoder उदाहरण पास किया गया है जिसका उपयोग आप अपने राज्य को एन्कोड करने के लिए कर सकते हैं। यही वह जगह है जहां आप अपने कस्टम-स्कीम यूआरएल को एन्कोड करेंगे, साथ ही आपके राज्य को सहेजने/पुनर्स्थापित करने के लिए आपको किसी भी अन्य संबंधित डेटा के साथ। फिर आप उस स्थिति को restoreWindowWithIdentifier:state:completionHandler: विधि में डीकोड करेंगे।

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

+2

यह शुरू करने में एक बड़ी मदद थी। यह पता चला कहानी अधिक जटिल है: यह वास्तव में NSDocument, नहीं NSWindow, जो * दस्तावेज़ एन्कोडिंग के लिए जिम्मेदार है है * राज्य (गिने आईडी, यूआरएल, हाल के परिवर्तन, प्रकार है) '-encodeRestorableStateWithCoder के अपने स्वयं के कार्यान्वयन में:'। NSDocumentController दस्तावेज़ को पुनर्स्थापित करने के लिए उस राज्य की जानकारी का उपयोग करता है, फिर '-मेकविंडो कंट्रोलर' और एनएसएप्लिकेशंस (या एनएसएप्लिकेशंस के समापन हैंडलर) को आमंत्रित करता है?) विंडो को पुनर्स्थापित करता है। साथ ही, NSDocumentController के कस्टम उप-वर्ग का उपयोग करते समय, ऐपकिट सेट * उस * वर्ग को 'बहाली क्लास' के रूप में सेट करता है। – paulmelnikow