2017-03-27 11 views
0

私は去年ここで紹介した問題を再訪しています。私は質問を正しく聞かず、関連するコードを提供しなかったと信じています。私はその質問を削除し、より良い言い直しをしました。今回は、私の質問を理解できる人がいることを願っています。エラーが表示されるまでに画面が長すぎたり、iOS 10.2がiCloudの新しいアクセス許可を実装していませんか? テキストファイルをiCloudに読み書きするユニバーサルiOS(およびmacOSバージョン)アプリを持っています。iCloudにファイルを書き込むことは問題ありません。 iPadがファイルを書き出すと、それをアプリに戻すことができますが、同じアプリを使用してiPhoneから書き込まれたファイルを読み取ることはできません。 (2)iPhoneがファイルを書き出すと、同じアプリを使ってiPadから書き出されたファイルを読み取ることはできません。 (3)Macは、iOS dによって書き込まれたファイルを読み取ることができますiOSデバイスはmacOSデバイスによって書き出されたファイルを読み取ることができません。iOSデバイスが別のiOSデバイスで作成されたiCloudアカウントにアクセスできない

ファイルを読み取ろうとすると、エラーコード260 - そのファイルは存在しません。これは上記の各ステップで発生します。それは同じ普遍的なアプリだから、それは私を完全に馬鹿にしてしまった。デバイスはファイル名にデバイス固有のものを追加しません。これは、iCloudファイルをデバイスにキャッシュすることについて誤解していることを意味します。私は、iOS(とmacOS)がこれを自動的にとることを理解しました。

ここに私のiOSプロジェクトのコードがあります。

これは私が(iOSのプロジェクトで)のiCloudからのファイルのURLを取得するにはmetaDataQueryを設定する方法である:

//Get list of iCloud files or read a file from iCloud 

func iCloud_ListOrReadFiles(_ accountName:String) 
{ 

    //Format for search predicate of document(s) in iCloud storage 
    var theFormat  :String 

    //List documents or open a document 
    if(listMode) 
    { 
     requestedAccountName = kSuffix //List all files with suffix kSuffix (= "txt") 
     theFormat = "%K ENDSWITH %@" //Just like all text documents 
    } else { 
     requestedAccountName = accountName //Read the file 
     theFormat = "%K LIKE %@" 
    } 

//そして今metaDataQuery metadataQuery = NSMetadataQuery() metadataQueryを設定します!述語= NSPredicate.init(形式:!theFormat、NSMetadataItemFSNameKey、requestedAccountName)

metadataQuery!.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope] 

    NotificationCenter.default.addObserver(self,selector:#selector(metadataQueryDidFinishGathering), 
             name:NSNotification.Name.NSMetadataQueryDidFinishGathering,object:metadataQuery) 
    metadataQuery!.start() 
} 

これは、私は、ファイルのURLは(iOSのプロジェクトに)metaDataQuery経由のiCloudから返された処理方法である:

func metadataQueryDidFinishGathering(通知:通知) { let query = notification.object!として! NSMetadataQuery

query.disableUpdates() //Disable the querying updates 
    NotificationCenter.default.removeObserver(self, name:NSNotification.Name.NSMetadataQueryDidFinishGathering, object:query) //And remove from Notifications 
    query.stop() //Final nail in the coffin for this query 

    let results = NSArray.init(array: query.results) 
    let theCount = query.resultCount 

    //Vamoose if nothing found 
    if (theCount < 1) { 
     return 
    } 

    if(listMode) //Just create a list of iCloud files found 
    { 
     listMode = false 

     for i in 0..<theCount 
     { 
      let account = Accounts() 
      account.startDate = nil 
      account.stopDate = nil 
      account.modDate  = nil //Can't set it below because the compiler is chocking up there. 
      account.location = 2 

      let urlString = ((results[i] as AnyObject).value(forAttribute: NSMetadataItemURLKey) as! URL).lastPathComponent 
      account.accountName = String((urlString as NSString).deletingPathExtension) 

      listOfAccounts?.add(account) 
     } 

     //If user wants the list sorted alphabetiucally, then do it 
     if(appSettings.bSortingsFlag) 
     { 
      if((((listOfAccounts?.count)!-1)) > onDeviceIndex) { //Sort only iCloud accounts 
       self.bubbleSortAccountNames(onDeviceIndex, toIndex:((listOfAccounts?.count)!-1)) 
      } 
     } 
    } else {  //Came here to read one text file 
     ubiquityURL = ((results[0] as AnyObject).value(forAttribute: NSMetadataItemURLKey) as? URL)! //URL of file 

     print(String(format:"metadataQueryDidFinishGathering:ubiquityURL = %@", ubiquityURL! as CVarArg)) //Let's see it 

     copyFromiCloud2Device(ubiquityURL! as NSURL) //Copy the file from iCloud (in the function below) 
} 

これは、metaDataQueryから返されたiCloud URLを使用して、ファイルをiCloudから読み取る方法です。コードの下(iOSのプロジェクトで)コンソール版画です:

/* コピー標準NSFilemanager方法copyItemAtURL ませんUIDocumentクラスを使用してのiCloudからテキストファイルがここ */ を使用FUNC copyFromiCloud2Device(_ iCloudURL:NSURL) { let nameWithSuffix = iCloudURL.lastPathComponent! //ファイル名(およびターゲットに使用する接尾辞)だけを抽出する deviceURL = CPLib()を実行します。fullURLPath(nameWithSuffix、inFolder:ゼロ)// My機能は、デバイス上のドキュメントフォルダへのフルパスを取得する

print("copyToDeviceDocumentsFolder:iCloudURL \(iCloudURL)") 
    print("copyToDeviceDocumentsFolder:deviceURL \(deviceURL)") 

    do { 
     try FileManager.default.copyItem(at: iCloudURL as URL, to:deviceURL) //Now copy the file from iCloud 

     //Process the contents after 0.25 seconds 
     Timer.scheduledTimer(timeInterval: 0.25, target:self, selector:#selector(converText2CoreData), userInfo:nil,repeats:false) 
    } catch let error as NSError { // End up here with error (code 260 = The file doesn't exist) 
      print("copyToDeviceDocumentsFolder:nameWithSuffix = \(nameWithSuffix)") 
     let noSuffix = String((nameWithSuffix as NSString).deletingPathExtension) //Remove the text suffix because user doesn't need to know that 
     let title = String(format:"Copy '%@' from iCloud",noSuffix!) 
     let errorDescription = String(format:"Error (%d), %@",error.code, error.localizedFailureReason!) 
     CPLib().showAlert(title, message:errorDescription, button:["Done"], calledBy:self, action:nil) 
    } 
} 

これらはでprint文です:(iOSのプロジェクトで) "metadataQueryDidFinishGathering" と "CopyFromiCloud2Device":

metadataQueryDidFinishGathering:ubiquityURL =ファイル:///private/var/mobile/Library/Mobile%20Documents/UZMZA52SXK~com~macsoftware~CheckPad/Documents/DemAccount.txt

copyToDeviceDocumentsFolder:iCloudURLファイル:///プライベート/var/mobile/Library/Mobile%20Documents/UZMZA52SXK~com~macsoftware~CheckPad/Documents/DemAccount.txt copyToDeviceDocumentsFolder:deviceURLファイル:///var/mobile/Containers/Data/Application/DF9EE5C0-E3EA-444A-839D-C2E8C1D1B408/Documents/DemAccount.txt copyToDeviceDocumentsFolder:読み取りに失敗しましたnameWithSuffix = DemAccount.txt

+ ++++++++++++ これはiCloud上から同じテキストファイルを読み取るためのMacOSで使用Objective Cのコード(作品)である:標準NSFilemanagerメソッドを使用して

/* コピーのiCloudからファイルcopyItemAtURLとNOT setUbiquitousです。 いいえUIDocumentは、ここで を使用するクラスを実装*/ - (ボイド)copyFromiCloud:(NSStringの*)ファイル名 {NSStringの* nameWithExtension = [ファイル名stringByAppendingPathExtension:kTEXTOne]。 NSURL * deviceURL = [[CoreDataStuff accountsLocation:nil] URLByAppendingPathComponent:nameWithExtension]; NSURL * iCloudURL = [ubiquityContainerURL URLByAppendingPathComponent:nameWithExtension];

NSFileManager *fileManager = [[NSFileManager alloc] init]; 
NSError *error = nil; 

//Copy the file from iCloud to local directory "Documents" on device 
BOOL success = [fileManager copyItemAtURL:iCloudURL toURL:deviceURL error:&error]; 

if (!success) 
    [self showAnAlert:[NSString stringWithFormat:@"Copy %@ from iCloud",fileName] //Private library call 
       message:[NSString stringWithFormat:@"Aborting...%@",[error localizedFailureReason]] altButton:nil]; 
else { 
    [NSTimer scheduledTimerWithTimeInterval:0.25 //Set up a timer to fire up after .25 seconds 
            target:self 
            selector:@selector(convertText2CoreData:) //My function to convert the data to CoreData 
            userInfo:nil 
            repeats:NO]; 
} 

}

私はまた、iOSデバイスがファイルを見つけることに失敗した場合、これはXcodeのコンソールに表示されていることに気づいた:iPadやiPhone上で実行

**** ** **

2017-03-25 20:09:15.543784 [MC] systemgroup.com.apple.configurationprofilesのシステムグループコンテナは、/ private/var/containers/Shared/SystemGroup/systemgroupです。 .com.apple.configurationprofiles 2017-03-25 20:09:15.554 561 CheckPad [405:66745] [MC]有効な有効なユーザー設定を読み込みます。

答えて

0

アップルのiOSの概要を読んだ後、私のiCloudファイルへのアクセスが失敗した理由を発見しました。 iOSはデバイス上に「iCloudコンテナ」領域を保持します。 iCloudから読み込むために、OSはファイルのこのローカル記憶域(ユビキタスコンテナとも呼ばれます)を調べます。見つからない場合は、エラーコード260 - そのファイルは存在しません。以前にiCloudに保存されているファイルは、ローカルストレージから読み込むだけです。ファイルが別のデバイスによって変更された場合(後日)、iCloudからそのバージョンがダウンロードされます。これを解決する 、私は単に

"FileManager.default.startDownloadingUbiquitousItem(時:iCloudURL)" を使用:

DispatchQueue "metadataQueryDidFinishGathering" によって返されたURLに

を、その後に2秒のためにそれを遅らせます.main.asyncAfter(期限:.now()+。秒(1)、実行:{ ファイルをここにダウンロードするコード }

コードをダウンロードしてください。これまでこれまでに働いています。

関連する問題