iCloud मूल बातें और कोड नमूना [बंद]


85

एक शुरुआत के रूप में, मैं iCloud के साथ संघर्ष कर रहा हूं। कुछ नमूने हैं, लेकिन वे आमतौर पर काफी विस्तृत हैं (डेवलपर मंच पर आईक्लाउड और कोरडाटा के लिए एक है जो बड़े पैमाने पर है)। सेब डॉक्स ठीक कर रहे हैं, लेकिन मैं अभी भी बड़ी तस्वीर नहीं देख सकता। तो कृपया मेरे साथ सहन करें, इनमें से कुछ प्रश्न काफी मौलिक हैं, लेकिन उत्तर देने में संभवतः आसान हैं।

संदर्भ: मेरे पास एक बहुत ही सरल आईक्लाउड ऐप चल रहा है (नीचे पूर्ण नमूना कोड)। उपयोगकर्ता को केवल एक UITextView दिखाया गया है और उसके इनपुट को text.txt नामक फ़ाइल में सहेजा गया है।

यहाँ छवि विवरण दर्ज करें

Txt फ़ाइल को क्लाउड पर धकेल दिया जाता है और सभी उपकरणों के लिए उपलब्ध कराया जाता है। पूरी तरह से काम करता है, लेकिन:

मुख्य समस्या: उन उपयोगकर्ताओं के बारे में जो iCloud का उपयोग नहीं करते हैं?

जब मैं अपना ऐप लॉन्च करता हूं (नीचे कोड देखें), मैं जांचता हूं कि क्या उपयोगकर्ता के पास आईक्लाउड सक्षम है। यदि iCloud सक्षम है, तो सब कुछ ठीक है। ऐप आगे बढ़ता है और क्लाउड में text.txt की तलाश करता है। यदि पाया जाता है, तो वह इसे लोड करेगा और उपयोगकर्ता को प्रदर्शित करेगा। यदि text.txt क्लाउड में नहीं पाया जाता है, तो यह बस एक नया text.txt बनाएगा और उपयोगकर्ता को प्रदर्शित करेगा।

यदि उपयोगकर्ता के पास iCloud सक्षम नहीं है, तो कुछ भी नहीं होगा। मैं यह कैसे संभव करूंगा कि गैर-iCloud उपयोगकर्ता अभी भी मेरे टेक्स्ट ऐप के साथ काम कर सकें? या मैं बस उन्हें अनदेखा करूँ? क्या मुझे गैर-आईक्लाउड उपयोगकर्ताओं के लिए अलग-अलग कार्य लिखने की आवश्यकता होगी? Ie फ़ंक्शन जिसमें मैं दस्तावेज़ फ़ोल्डर से एक text.txt लोड करता हूं?

Apple लिखते हैं :

ICloud में फ़ाइलों का इलाज उसी तरह से करें जैसे आप अपने ऐप सैंडबॉक्स में अन्य सभी फ़ाइलों का इलाज करते हैं।

हालाँकि, मेरे मामले में अब कोई 'सामान्य' ऐप सैंडबॉक्स नहीं है। यह बादल में है। या क्या मैं हमेशा डिस्क से अपना text.txt लोड करता हूं और फिर iCloud से जांचता हूं कि क्या कुछ और अप-टू-डेट है?

संबंधित समस्या: फ़ाइल संरचना - सैंडबॉक्स बनाम क्लाउड

शायद मेरी मुख्य समस्या एक गलतफहमी है कि iCloud को कैसे काम करना चाहिए। जब मैं UIDocument का एक नया उदाहरण बनाता हूं, तो मुझे दो विधियों को अधिलेखित करना होगा। पहले - (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outErrorक्लाउड से फाइल प्राप्त करने के लिए और फिर -(id)contentsForType:(NSString *)typeName error:(NSError **)outErrorक्लाउड में फाइल प्राप्त करने के लिए।

क्या मुझे अलग-अलग कार्यों को शामिल करना होगा जो मेरे सैंडबॉक्स में text.txt की एक स्थानीय प्रतिलिपि भी बचाएगा? क्या यह गैर-आईक्लाउड उपयोगकर्ताओं के लिए काम करेगा? जैसा कि मैं iCloud को समझता हूं, यह text.txt की एक स्थानीय प्रतिलिपि को स्वचालित रूप से बचाएगा। इसलिए मुझे अपने ऐप के 'पुराने' सैंडबॉक्स में कुछ भी सेव करने की कोई आवश्यकता नहीं होनी चाहिए (जैसे कि यह पुराने, प्री-आईक्लाउड दिनों में हुआ करता था)। अभी, मेरा सैंडबॉक्स पूरी तरह से खाली है, लेकिन मुझे नहीं पता कि यह सही है या नहीं। क्या मुझे वहाँ में text.txt की एक और कॉपी रखनी चाहिए? यह मेरी डेटा संरचना को अव्यवस्थित करने जैसा लगता है ... जैसे कि क्लाउड में एक टेक्स्ट.टैक्स है, एक मेरे डिवाइस पर आईक्लाउड सैंडबॉक्स में है (जो कि ऑफ़लाइन होने पर भी काम करेगा), और अच्छे पुराने सैंडबॉक्स में एक तीसरा मेरा ऐप ...


मेरा कोड: एक साधारण iCloud नमूना कोड

यह शिथिल रूप से एक उदाहरण पर आधारित है जो मुझे डेवलपर फोरम में और डब्ल्यूडब्ल्यूडीसी सत्र वीडियो पर मिला। मैंने उसे नंगे न्यूनतम तक छीन लिया। मुझे यकीन नहीं है कि मेरी एमवीसी संरचना कोई अच्छी है। मॉडल AppDelegate में है जो आदर्श नहीं है। इसे बेहतर बनाने के किसी भी सुझाव का स्वागत है।


संपादित करें: मैंने मुख्य प्रश्न निकालने की कोशिश की और इसे [यहाँ] पोस्ट किया। 4


अवलोकन:

अवलोकन

सबसे महत्वपूर्ण बिट जो क्लाउड से text.txt को लोड करता है:

//  AppDelegate.h
//  iCloudText

#import <UIKit/UIKit.h>

@class ViewController;
@class MyTextDocument;

@interface AppDelegate : UIResponder <UIApplicationDelegate> {
    NSMetadataQuery *_query;
}

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *viewController;
@property (strong, nonatomic) MyTextDocument *document;

@end

//  AppDelegate.m
//  iCloudText

#import "AppDelegate.h"
#import "MyTextDocument.h"
#import "ViewController.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;
@synthesize document = _document;

- (void)dealloc
{
    [_window release];
    [_viewController release];
    [super dealloc];
}

- (void)loadData:(NSMetadataQuery *)query {

    // (4) iCloud: the heart of the load mechanism: if texts was found, open it and put it into _document; if not create it an then put it into _document

    if ([query resultCount] == 1) {
        // found the file in iCloud
        NSMetadataItem *item = [query resultAtIndex:0];
        NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];

        MyTextDocument *doc = [[MyTextDocument alloc] initWithFileURL:url];
        //_document = doc;
        doc.delegate = self.viewController;
        self.viewController.document = doc;

        [doc openWithCompletionHandler:^(BOOL success) {
            if (success) {
                NSLog(@"AppDelegate: existing document opened from iCloud");
            } else {
                NSLog(@"AppDelegate: existing document failed to open from iCloud");
            }
        }];
    } else {
        // Nothing in iCloud: create a container for file and give it URL
        NSLog(@"AppDelegate: ocument not found in iCloud.");

        NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
        NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:@"text.txt"];

        MyTextDocument *doc = [[MyTextDocument alloc] initWithFileURL:ubiquitousPackage];
        //_document = doc;
        doc.delegate = self.viewController;
        self.viewController.document = doc;

        [doc saveToURL:[doc fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
            NSLog(@"AppDelegate: new document save to iCloud");
            [doc openWithCompletionHandler:^(BOOL success) {
                NSLog(@"AppDelegate: new document opened from iCloud");
            }];
        }];
    }
}

- (void)queryDidFinishGathering:(NSNotification *)notification {

    // (3) if Query is finished, this will send the result (i.e. either it found our text.dat or it didn't) to the next function

    NSMetadataQuery *query = [notification object];
    [query disableUpdates];
    [query stopQuery];

    [self loadData:query];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
    _query = nil; // we're done with it
}

-(void)loadDocument {

    // (2) iCloud query: Looks if there exists a file called text.txt in the cloud

    NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
    _query = query;
    //SCOPE
    [query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
    //PREDICATE
    NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K == %@", NSMetadataItemFSNameKey, @"text.txt"];
    [query setPredicate:pred];
    //FINISHED?
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
    [query startQuery];

}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"AppDelegate: app did finish launching");
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil] autorelease];
    } else {
        self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil] autorelease];
    }

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];

    // (1) iCloud: init

    NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
    if (ubiq) {
        NSLog(@"AppDelegate: iCloud access!");
        [self loadDocument];
    } else {
        NSLog(@"AppDelegate: No iCloud access (either you are using simulator or, if you are on your phone, you should check settings");
    }


    return YES;
}

@end

UIDocument

//  MyTextDocument.h
//  iCloudText

#import <Foundation/Foundation.h>
#import "ViewController.h"

@interface MyTextDocument : UIDocument {

    NSString *documentText;
    id delegate;

}

@property (nonatomic, retain) NSString *documentText;
@property (nonatomic, assign) id delegate;

@end

//  MyTextDocument.m
//  iCloudText

#import "MyTextDocument.h"
#import "ViewController.h"

@implementation MyTextDocument

@synthesize documentText = _text;
@synthesize delegate = _delegate;

// ** READING **

- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError
{
    NSLog(@"UIDocument: loadFromContents: state = %d, typeName=%@", self.documentState, typeName);

    if ([contents length] > 0) {
        self.documentText = [[NSString alloc] initWithBytes:[contents bytes] length:[contents length] encoding:NSUTF8StringEncoding];
    }
    else {
        self.documentText = @"";
    }

    NSLog(@"UIDocument: Loaded the following text from the cloud: %@", self.documentText);


    // update textView in delegate...
    if ([_delegate respondsToSelector:@selector(noteDocumentContentsUpdated:)]) {
        [_delegate noteDocumentContentsUpdated:self];
    }

    return YES;

}

// ** WRITING **

-(id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
    if ([self.documentText length] == 0) {
        self.documentText = @"New Note";
    }

    NSLog(@"UIDocument: Will save the following text in the cloud: %@", self.documentText);

    return [NSData dataWithBytes:[self.documentText UTF8String] length:[self.documentText length]];
}
@end

VIEWCONTROLLER

//
//  ViewController.h
//  iCloudText

#import <UIKit/UIKit.h>

@class MyTextDocument;

@interface ViewController : UIViewController <UITextViewDelegate> {

    IBOutlet UITextView *textView;

}

@property (nonatomic, retain) UITextView *textView;
@property (strong, nonatomic) MyTextDocument *document;

-(void)noteDocumentContentsUpdated:(MyTextDocument *)noteDocument;

@end

//  ViewController.m
//  iCloudText

#import "ViewController.h"
#import "MyTextDocument.h"

@implementation ViewController

@synthesize textView = _textView;
@synthesize document = _document;

-(IBAction)dismissKeyboard:(id)sender {

    [_textView resignFirstResponder];

}

-(void)noteDocumentContentsUpdated:(MyTextDocument *)noteDocument
{
    NSLog(@"VC: noteDocumentsUpdated");
    _textView.text = noteDocument.documentText;
}

-(void)textViewDidChange:(UITextView *)theTextView {

     NSLog(@"VC: textViewDidChange");
    _document.documentText = theTextView.text;
    [_document updateChangeCount:UIDocumentChangeDone];

}

4
मैं वास्तव में सवालों के एक जोड़े में इसे तोड़ने का सुझाव था। मुझे यहां कुछ अलग-अलग प्रश्न दफन हैं, और आपके द्वारा यहां दी गई पाठ की दीवार में उन्हें चुनना मुश्किल है। मैं इस सवाल को वापस करने के बारे में पूछ रहा हूं कि उन लोगों के लिए क्या करना है जिनके पास iCloud सक्षम नहीं है, और दूसरों को (आपके नमूना कोड के केवल प्रासंगिक भागों के साथ) अलग-अलग प्रश्नों में तोड़ दें। वे अच्छे प्रश्न हैं, लेकिन मुझे लगता है कि उन्हें अलग कर दिया जाना चाहिए।
ब्रैड लार्सन

@BradLarson आपकी टिप्पणी के लिए धन्यवाद। मुझे क्षमा करें यदि प्रश्न (ओं) को थोड़ा सा एक साथ मिलाया जाता है, लेकिन मुझे लगता है कि मुख्य प्रश्न (जैसा कि मैंने संकेत करने की कोशिश की) ऐप सैंडबॉक्स बनाम आईक्लाउड सैंडबॉक्स समस्या है। मैंने पूर्ण कोड प्रदान किया (जो कि सबसे छोटा आईक्लाउड कोड उदाहरण है, btw) जैसा कि मैंने सोचा था कि ENTIRE संदर्भ यह जानने के लिए महत्वपूर्ण है कि क्या हो रहा है ... लेकिन मैं बस एक और प्रश्न खोल सकता हूं और इसे इस प्रश्न से वापस लिंक कर सकता हूं बड़ा चित्र मिलता है।
n.evermind

@BradLarson ठीक है, मैंने एक नया सवाल यहाँ खोला: stackoverflow.com/questions/7798555/…
n.evermind

उन लोगों के लिए जो अभी भी कोर डेटा पर एक हैंडल पाने की कोशिश कर रहे हैं और iCloud इस लिंक की कोशिश करें ossh.com.au/design-and-technology/software-development/…
डंकन

बंद नहीं किया जाना चाहिए यह वास्तव में अधिक रचनात्मक पदों में से एक है जिसे मैंने iCloud पर देखा है ..
एंड्रयू स्मिथ

जवाबों:


22

मैं केवल डॉक्स फिर से पढ़ता हूं और ऐसा प्रतीत होता है कि मेरा सामान्य दृष्टिकोण गलत है। मुझे पहले सैंडबॉक्स में फ़ाइल बनाना चाहिए और फिर इसे क्लाउड पर ले जाना चाहिए। दूसरे शब्दों में, Apple को लगता है कि मुझे हर समय एक ही फ़ाइल के तीन संस्करण चाहिए: मेरे ऐप की निर्देशिका में एक, मेरे डिवाइस के iCloud दानव निर्देशिका में एक (जो कि ऑफ़लाइन होने पर भी सुलभ है) और एक में बादल:

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

फ़ाइल या निर्देशिका को iCloud में ले जाने के लिए:

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

URLForUbiquityContainerIdentifier: iCloud कंटेनर निर्देशिका के लिए एक URL प्राप्त करने के लिए विधि का उपयोग करें जिसमें आप आइटम को संग्रहीत करना चाहते हैं। ICloud में आइटम का स्थान निर्दिष्ट करने वाले नए URL के निर्माण के लिए कंटेनर निर्देशिका URL का उपयोग करें। SetUbiquitous: itemAtURL: DestURL: त्रुटि: NSFileManager की विधि को आईक्लाउड में ले जाने के लिए कॉल करें। अपने ऐप के मुख्य थ्रेड से इस विधि को कभी भी कॉल न करें; ऐसा करने से आपके मुख्य थ्रेड को समय की विस्तारित अवधि के लिए अवरुद्ध किया जा सकता है या आपके ऐप के स्वयं के फ़ाइल प्रस्तरों में से एक के साथ गतिरोध पैदा हो सकता है। जब आप एक फ़ाइल या निर्देशिका को iCloud में स्थानांतरित करते हैं, तो सिस्टम उस आइटम को आपके ऐप सैंडबॉक्स से बाहर निकालता है और एक निजी स्थानीय निर्देशिका में रखता है ताकि इसे iCloud डेमन द्वारा मॉनिटर किया जा सके। भले ही फ़ाइल आपके सैंडबॉक्स में नहीं है, फिर भी आपके ऐप की पूरी पहुंच है। हालाँकि फ़ाइल की एक प्रतिलिपि वर्तमान डिवाइस के लिए स्थानीय रहती है, फ़ाइल को iCloud पर भी भेजा जाता है ताकि इसे अन्य डिवाइसों में वितरित किया जा सके। ICloud डेमन यह सुनिश्चित करने के काम को संभालता है कि स्थानीय प्रतियां समान हैं। तो आपके ऐप के नजरिए से, फ़ाइल सिर्फ iCloud में है।

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

हालाँकि, यदि आप सेट्विकिटस के विषय में डॉक्स में थोड़ा गहरा खुदाई करते हैं, तो आप पाएंगे:

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

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


1
url लिंक टूटा है ...
ngb

5

मैं आपके उदाहरण का उपयोग कर रहा हूं और मुझे iCloud की मूल बातें समझने में मदद करने के लिए यह पसंद है। अब मैं अपने स्वयं के ऐप के लिए आपके प्रश्न से जूझ रहा हूं, जिसे ऐप के मौजूदा उपयोगकर्ताओं को स्थानीय रूप से संग्रहीत सामग्री के साथ समर्थन करना है जो इन मामलों को बनाने के लिए iCloud का उपयोग कर रहे हैं या नहीं कर सकते हैं जहां तक ​​मैं बता सकता हूं:

मामले:

  1. नया उपयोगकर्ता
    • icloud है - icloud में दस्तावेज़ बनाएँ
    • कोई icloud नहीं - स्थानीय रूप से दस्तावेज़ बनाएं
  2. मौजूदा उपयोगकर्ता
    • icloud है
      • बस जोड़ा गया - स्थानीय डॉक्स को आईक्लाउड पर माइग्रेट करें
      • नहीं जोड़ा - icloud के लिए डॉक्स खोलें / सहेजें
    • कोई आईक्लाउड नहीं
      • अभी निकाला गया - पूर्व icloud डॉक्स को स्थानीय पर माइग्रेट करें
      • न केवल हटाए गए - डॉक्स को स्थानीय में खोलें / सहेजें

अगर कोई iCloud हटाता है - सर्वव्यापी URL रिटर्न नील पर कॉल नहीं करेगा? अगर ऐसा है तो मैं डॉक्स को वापस स्थानीय भंडारण में कैसे स्थानांतरित करूं? मैं अभी के लिए एक उपयोगकर्ता प्रीफ़ बनाऊंगा, लेकिन वर्कअराउंड का एक सा लगता है।

मुझे लगता है कि मुझे यहाँ कुछ स्पष्ट याद आ रहा है इसलिए अगर कोई भी इसे देख सकता है, तो कृपया इसमें झंकार करें।


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

Developer.apple.com/library/ios/#documentation/DataManagement/… पर एक नज़र डालें, जो यह निर्धारित करने के लिए कुछ नमूना कोड देता है कि क्या स्थानीय सैंडबॉक्स या क्लाउड में कुछ डाला जाना चाहिए।
n.evermind

उसके लिए धन्यवाद। मैंने उस डॉक्टर को देखा था, लेकिन इससे पहले मैं अपने iCloud मिशन में था इसलिए मैं यह कोड भूल गया था। मैं स्थानीय और दूरस्थ का समर्थन करने के लिए अपने नमूने को अनुकूलित करने का प्रयास करने जा रहा हूं। मैं अभी भी स्पष्ट नहीं हूं कि हम उस उपयोगकर्ता को कैसे संभालते हैं जो iCloud को निष्क्रिय करता है क्योंकि हम सर्वव्यापी URL खो देते हैं, लेकिन मेरे पास एक दरार होगी और एक अद्यतन साझा करना होगा।
अर्जक

1
तो एक तरह से, यह थोड़ा बेवकूफ है कि हमें स्थानीय सैंडबॉक्स के लिए क्लाउड और पैट के लिए URL का उपयोग करना होगा। यह अच्छा होगा यदि iCloud हमारे लिए सब कुछ संभाल सकता है ... लेकिन इस तरह, हमें मूल रूप से हमारे द्वारा खोली गई प्रत्येक फ़ाइल के लिए दो अलग-अलग तरीकों को कोड करने की आवश्यकता है।
n.evermind

मैंने अभी आपकी पोस्ट पढ़ी। मैं अब NSUserDefaults में उपयोगकर्ता की वरीयता (यानी उपयोगकर्ता चाहता है / iCloud का उपयोग नहीं करना चाहता) को सहेज रहा हूं। एप्पल का भी यही कहना है। मैं हमेशा जांचता हूं कि क्या आईक्लाउड सुलभ है। यदि यह सुलभ नहीं है, तो मैं उपयोगकर्ताओं को इसे चालू करने के लिए कहता हूं - लेकिन केवल अगर उन्होंने स्पष्ट रूप से ऐप को नहीं बताया है कि वे इसका उपयोग नहीं करना चाहते हैं। अन्यथा यह उन लोगों के लिए कष्टप्रद हो जाता है जो आईक्लाउड का उपयोग नहीं करना चाहते हैं। एक बार जब मैंने निर्धारित कर लिया है कि अगर iCloud सक्षम है, तो मैं या तो सर्वव्यापी URL मार्ग का पालन करूंगा और UIDocument का उपयोग करूंगा या केवल अच्छे पुराने दिनों की तरह सैंडबॉक्स से फाइलें खोलूंगा।
n.evermind

4

यदि आप चाहते हैं कि उपयोगकर्ता प्री-iOS 5.0 वाले उपकरणों के बीच पाठ साझा करने में सक्षम हों, तो आपको iCloud से पहले सभी को क्या करना होगा और अपने स्वयं के सर्वर पर जानकारी स्थानांतरित करनी होगी।

आपको वास्तव में कहीं न कहीं एक सर्वर की आवश्यकता होती है जो आपके ऐप को अपनी पाठ फ़ाइलों को सहेजने और उन्हें एक उपयोगकर्ता खाते के साथ जोड़ने की सुविधा देता है।

आपको एक खाता बनाने के लिए उपयोगकर्ताओं की आवश्यकता होगी और आपको एक डिवाइस पर नई जानकारी को अपने स्वयं के 'क्लाउड' में स्थानांतरित करने की आवश्यकता होगी।

उपयोगकर्ता अन्य उपकरणों पर एक ही खाते के साथ पंजीकरण करेंगे और आपको यह पता लगाने की देखभाल करने की आवश्यकता होगी कि किसी अन्य डिवाइस ने आपके स्वयं के क्लाउड पर डेटा स्थानांतरित कर दिया है, और नई जानकारी के साथ वर्तमान डिवाइस को अपडेट करें।

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


धन्यवाद। इसलिए दूसरे शब्दों में, अगर मैं प्री-आईओएस 5 डिवाइस का समर्थन नहीं करना चाहता हूं, तो मैं केवल यूआईडीक्यूमेंट के साथ जा रहा हूं और अपने ऐप के सैंडबॉक्स में डॉक्टर निर्देशिका की सामग्री के बारे में भूल गया हूं।
n.evermind

बहुत ज्यादा, हालाँकि जहाँ तक मैं बता सकता हूँ, आपके पास अभी भी सैंडबॉक्स में एक दस्तावेज होगा, जिसे UIDocument आपके लिए iCloud के साथ मध्यस्थता करने में मदद करेगा, लेकिन आपको बताया जाएगा कि आप इसे कब एक्सेस कर सकते हैं ... मुझे अभी भी मिल रहा है इस सामान के साथ खुद को पकड़ना है!
जोनाथन वॉटम

3

ऐसा नहीं लगता है कि आप एक iCloud / notICloud मुद्दे से अधिक iOS5 / notIOS5 समस्या से जूझ रहे हैं।

यदि आपका परिनियोजन लक्ष्य iOS5 है, तो बस हमेशा UIDocument संरचना का उपयोग करें। यदि यह सर्वव्यापी है, तो आपका NSMetaDataQuery इसे क्लाउड में मिलेगा; यदि यह डिवाइस पर नहीं मिलेगा।

यदि, दूसरी ओर, आप अपने ऐप में प्री 5.0 एक्सेस प्रदान करना चाहते हैं, तो आपको यह देखने के लिए सशर्त रूप से जांचने की आवश्यकता होगी कि क्या रनिंग आईओएस 5.0 या अधिक है या नहीं। यदि यह है तो UIDocument का उपयोग करें; यदि नहीं, तो पुराने तरीके से डेटा पढ़ें / लिखें।

मेरा दृष्टिकोण एक सशर्त saveData विधि लिखना था जो iOS5 के लिए जाँच करता है। यदि यह मौजूद है तो मैं परिवर्तन गणना (या किसी पूर्व प्रबंधक का उपयोग) को अपडेट करता हूं। आपके मामले में textViewDidChange इस पद्धति को कॉल करेगा। यदि नहीं, तो यह पुराने तरीके से डिस्क को सहेजता है। लोड करने पर, विपरीत होता है।


1

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

हालाँकि, आप कुछ ऐसा बना रहे हैं जो iCloud जैसी कार्यक्षमता पर निर्भर करता है। आप उस स्टेटमेंट पर पकड़ नहीं बना सकते क्योंकि आपका ऐप iCloud पर निर्भर करता है कि वह जिस तरह से काम करना चाहता है उसके लिए कुछ भी मौजूद हो। आपको या तो अपना ऐप बंद करना होगा और बस "कृपया इसे काम करने के लिए iCloud सेटअप करें" या iCloud जैसी कार्यक्षमता (अपने खुद के या किसी और के) की नकल करें, जिसे आप हमेशा उपयोग कर सकते हैं, भले ही।


धन्यवाद। इसलिए मुझे लगता है कि मुझे यह चुनना होगा कि मैं iCloud केवल ऐप करता हूं या iCloud कार्यक्षमता को बदलने वाले लोगों के लिए किसी प्रकार का हाइब्रिड। जैसा कि iCloud इतना जटिल है, मैं तब केवल एक iCloud के लिए जाना चाहता हूं। धन्यवाद।
n.evermind
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.