locked
Cannot bring back a list of my documents stored on iCloud RRS feed

  • Question

  • User374304 posted

    I have code that works and has worked for a long time that backs up to the icloud and I have code that will restore a specific file when I pass the name of the file in. What I am looking for is a way to list the available documents in iCloud on my page, so a user can select one to restore, but no matter what I try, I do not get back a list of documents, I just get back nothing. I have scoured the internet to find a solution to my issue and nothing has worked. Here is my code to read the directory

    public async Task<string[]> GetFiles()
        {
            _baseUrl = NSFileManager.DefaultManager.GetUrlForUbiquityContainer(null);           
            iCloudUIDocument uid = new iCloudUIDocument(_baseUrl);            
            NSError error;                                      
            var files = NSFileManager.DefaultManager.GetDirectoryContent(makeUrl().Path, out error);   
            var allFiles = NSArray.FromStrings(files);
            uid.LoadFromContents(allFiles, UTType.Folder, out error);
            uid.ContentsForType(UTType.Folder, out error);
            return null;// file;
        }
    
        private NSUrl makeUrl(string fname = null)
        {            
            var url = _baseUrl.Append("Documents", true);
            if (fname != null) url = url.Append(fname, false);
            return url;
        }
    

    The problem that I am having is that the file array is empty all the time, no matter what I try.

    Here is the section I added to my info.plist which is supposed to make the hidden documents appear, but does not seem to work

    <key>NSUbiquitousContainers</key>
      <dict>
        <key>iCloud.com.???.????.MyApp</key>
        <dict>
          <key>NSUbiquitousContainerIsDocumentScopePublic</key>
          <true/>
          <key>NSUbiquitousContainerName</key>
          <string>MyApp</string>
          <key>NSUbiquitousContainerSupportedFolderLevels</key>
          <string>One</string>
        </dict>
      </dict>
    

    And my Entitlements.plist which I didn't touch has this

    <dict>
        <key>com.apple.developer.icloud-container-identifiers</key>
        <array>
            <string>iCloud.com.???.????</string>
        </array>
        <key>com.apple.developer.ubiquity-kvstore-identifier</key>
        <string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string>
        <key>com.apple.developer.icloud-services</key>
        <array>
            <string>CloudKit</string>
            <string>CloudDocuments</string>
        </array>
    </dict> 
    

    I am using VS 2019 on Windows and Xamarin iOS with C#

    Any help would be hugely appreciated. Thanks!

    Monday, June 1, 2020 10:56 PM

Answers

  • User369979 posted

    This code uses CloudKit to store records in the database. It is different from the document manipulation. There are no files. You used

    ThisApp.PrivateDatabase.SaveRecord
    

    to insert a record into the database. And if you want to query data using:

    database.PerformQuery(query, null, (records, error) =>
    {
    
    });
    

    Here is documentation demonstrating the details for your reference: https://docs.microsoft.com/en-us/xamarin/ios/data-cloud/intro-to-cloudkit

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 4, 2020 6:43 AM

All replies

  • User369979 posted

    Did you enable the iCloud capability on the Apple portal? Have you stored files on that path before reading? Could you get a valid _baseUrl? If so we could directly manipulate it to read and write files. Here is my code:

    var url = NSFileManager.DefaultManager.GetUrlForUbiquityContainer(null).Path;
    var folder = Path.Combine(url, "Documents");
    NSFileManager.DefaultManager.CreateDirectory(folder, true, null);
    
    var file = Path.Combine(folder, "text.txt");
    File.WriteAllText(file, "test");
    

    It tried to write a simple test file on iCloud. And I could retrieve the files successfully:

    NSError error;
    var files = NSFileManager.DefaultManager.GetDirectoryContent(folder, out error);
    
    Tuesday, June 2, 2020 3:27 AM
  • User374304 posted

    Hey, thanks so much for the response!

    Well, I have successfully been writing to the cloud and reading files back from it for a long time, but now I am trying to get the files names I have stored previously from the iCloud directory I have been storing all the files in and load the contents of the directory into an array of strings.

    Now, I think you raise a good point however, I have just been assuming that the directory found using this command, var url = NSFileManager.DefaultManager.GetUrlForUbiquityContainer(null).Path; Is the directory iCloud has automatically been storing my documents in, as I am not specifying a directory when storing them or when reading them back. But, maybe I am wrong in my assumption. When writing and reading, I am using different code which may store the records somewhere else

     public async Task BackupToiCloud(int autoId)
         {
            MileageItemRepository repository = new MileageItemRepository();
            string ReferenceItemRecordName = "MileageManager" + UIDevice.CurrentDevice.Name.Replace(" ", "").Trim() + DateTime.Now.ToString("MMddyyyy");
            //****** Only done for cleanup DO NOT UNCOMMENT ******
            //await repository.DropMileageTable();
            //****** Only done for cleanup DO NOT UNCOMMENT ******
    
            var success = false;
            var response = await repository.GetMileageData(autoId);
    
            foreach (var item in response)
            {
                // Create a new record on ICloud
                var newRecord = new CKRecord(ReferenceItemRecordName);
                newRecord["AutoId"] = (NSNumber)item.CarId;
                newRecord["Id"] = (NSNumber)item.Id;
                //newRecord["Date"] = (NSDate)item.Date;
                newRecord["StrDate"] = (NSString)item.StrDate;
                newRecord["Gas"] = (NSNumber)Convert.ToDouble(item.Gas);
                newRecord["Miles"] = (NSNumber)Convert.ToDouble(item.Miles);
                newRecord["Price"] = (NSNumber)Convert.ToDouble(item.Price);
                newRecord["MPG"] = (NSNumber)Convert.ToDouble(Math.Round(Convert.ToDecimal(item.Miles) / Convert.ToDecimal(item.Gas), 3).ToString());
                if (!string.IsNullOrWhiteSpace(item.Note))
                    newRecord["Note"] = (NSString)item.Note;
    
                var recordID = new CKRecordID(ReferenceItemRecordName);
    
                bkupCounter++;
    
                // Save it to iCloud
                ThisApp.PrivateDatabase.SaveRecord(newRecord, (record, err) =>
                {
                    // Was there an error?                                       
                    if (err != null)
                    {
                        SetUpErrorMessage(" In BackupToiCloud " + err.ToString(), false);
                    }
                });
                //await Task.Delay(500);               
            }
        }
    

    Is my assumption incorrect, does this code store my files in a different location? If so, how can I find that location? Or, is there a way to read the directory the files are stored in using this type functionality? If not, do I need to store and read my files using the coding practice in my original post? I would hate to have to do that as my back up and restore of files works so well currently, but whatever it takes.

    Let me know, and again, thanks so much for responding!

    Tuesday, June 2, 2020 11:31 PM
  • User369979 posted

    This code uses CloudKit to store records in the database. It is different from the document manipulation. There are no files. You used

    ThisApp.PrivateDatabase.SaveRecord
    

    to insert a record into the database. And if you want to query data using:

    database.PerformQuery(query, null, (records, error) =>
    {
    
    });
    

    Here is documentation demonstrating the details for your reference: https://docs.microsoft.com/en-us/xamarin/ios/data-cloud/intro-to-cloudkit

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 4, 2020 6:43 AM
  • User374304 posted

    I got is working... Thanks so much!

    Sunday, June 21, 2020 2:14 PM