0

I am working on an app that is a concept of storing .csv files in iCloud from different iPhone devices. The files are store function works fine if I have a login on the device with the same iCloud account which I have created the certificates. My app requirement was can I have to store .csv file into iCloud storage in different devices that may be the login with different apple account.

Below are the codes that I am using for file storage.

extension FarmerTVC{

private func createCSV() -> Void {
    let fileName = getDocumentsDirectory().appendingPathComponent(importFileName)
    var csvOutputText = "Name, Country, Latitude, Longitude\n"
    
    guard self.allFarmer?.count != 0 else{
        print("There have no active farmer list")
        return
    }
    
    print("........................Exporting the details....................")
    
    for farmerDetails in self.allFarmer! {
        let fullName = "\(farmerDetails.firstName) \(farmerDetails.middleName) \(farmerDetails.lastName)"
        
        let newDetails = "\(fullName),\(farmerDetails.country), \(farmerDetails.latitude), \(farmerDetails.longitude)\n"
        print("\(newDetails)")
        csvOutputText.append(newDetails)
    }
    
    self.removeExistFileFromDirectory()

    
    
    do {
        try csvOutputText.write(to: fileName, atomically: true, encoding: String.Encoding.utf8)
        print("........................Coplete Exporting the File....................\n \(fileName)")
        self.createDirectory()
        //CloudDataManager.sharedInstance.copyFileToCloud()
    } catch {
        print(".........................Failed to create file........................")
        print("\(error)")
    }
    //let activity = UIActivityViewController(activityItems: ["your results", fileName], applicationActivities: nil)
    //present(activity, animated: true)
}

private func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

private func removeExistFileFromDirectory(){
    let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let url = NSURL(fileURLWithPath: path)
    if let pathComponent = url.appendingPathComponent(importFileName) {
        let filePath = pathComponent.path
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: filePath) {
            print("File Alreday exist in the directory")
            do {
                try fileManager.removeItem(atPath: filePath)
                print("File removed from the directory")
            }catch{
                print("\(error)")
            }
        } else {
            print("FILE NOT AVAILABLE")
        }
    } else {
        print("FILE PATH NOT AVAILABLE")
    }
}}



extension FarmerTVC{
//Create iCloud Drive directory
func createDirectory(){
    if isICloudContainerAvailable() {
        if let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents") {
            if (!FileManager.default.fileExists(atPath: iCloudDocumentsURL.path, isDirectory: nil)) {
                do {
                    try FileManager.default.createDirectory(at: iCloudDocumentsURL, withIntermediateDirectories: true, attributes: nil)
                    print("File path not avaliable in the iCloud Drive")
                    self.copyDocumentsToiCloudDirectory()
                }
                catch {
                    //Error handling
                    print("Error in creating doc")
                }
            }else{
                print("Alreday Have the document path in the icloud.")
                self.copyDocumentsToiCloudDirectory()
            }
        }
    }
    else {
        self.ShowAlertMsg(title: "Oops!", msg: "Not logged into iCloud")
        
    }
}

//Copy files from local directory to iCloud Directory
func copyDocumentsToiCloudDirectory() {
    if isICloudContainerAvailable() {
        guard let localDocumentsURL = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: .userDomainMask).last else { return }
        
        let fileURL = localDocumentsURL.appendingPathComponent(importFileName)
        
        guard let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents").appendingPathComponent(importFileName) else { return }
        
        var isDir:ObjCBool = false
        
        if FileManager.default.fileExists(atPath: iCloudDocumentsURL.path, isDirectory: &isDir) {
            do {
                try FileManager.default.removeItem(at: iCloudDocumentsURL)
                print("Remove the old existing file from the iCloud drive")
            }
            catch {
                //Error handling
                print("Error in remove item")
            }
        }
        
        do {
            try FileManager.default.copyItem(at: fileURL, to: iCloudDocumentsURL)
            self.ShowAlertMsg(title: "Saved!", msg: "File saved into your iCloud drive")
        }
        catch {
            //Error handling
            print("Error in copy item")
        }
    }
    else {
        self.ShowAlertMsg(title: "Oops!", msg: "Not logged into iCloud")
        
    }
}

func ShowAlertMsg(title: String, msg: String) {
    let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertController.Style.alert)
    
    alert.addAction(UIAlertAction(title: "OK",
                                  style: UIAlertAction.Style.default,
                                  handler: {(_: UIAlertAction!) in
    }))
    self.present(alert, animated: true, completion: nil)
}

//To check user logged in to iCloud
func isICloudContainerAvailable() -> Bool {
    if FileManager.default.ubiquityIdentityToken != nil {
        return true
    }
    else {
        return false
    }
}}

info.plist file codes

Signing & Capabilities

It works fine for me if I have login into the same iCloud account on which I have created the certificates and iCloud container for the app. But I will not store the file in iCloud on different iCloud accounts. My Question was

  1. Can we store the file on different iCloud accounts? If yes then how?
  2. Can we use iCloud storage for the distribution of an app for different Apple id?
  3. How can I store .csv file into iCloud storage in different devices that may be the login with a different apple account?
halfer
  • 19,824
  • 17
  • 99
  • 186
Tapas_ios
  • 73
  • 6

1 Answers1

0

If you want to share files between multiple iCloud accounts across multiple devices, I suggest storing the files using CloudKit.

You would save the files as part of one or more CKRecords in the Public database of your application (not the private one). You can also make use of CKShare for sharing between specific individuals, but that takes a bit more work.

Apple only recently enabled shared files via iCloud Drive (iOS 13 and macOS 10.15), but as far as I know, there aren't APIs for doing this. Users must do it on their own. So your application can't manage the files unless you do this with CloudKit.

halfer
  • 19,824
  • 17
  • 99
  • 186
Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128