iosswiftnsuserdefaultsios8-share-extension

Share Data between Project and Share Extension


I would like to share data between my Main Project and my Share Extension. This is what I did:

1. enable App Groups in both Project & Share Extension

2. save data in Project inside viewDidLoad (works fine, I tested it):

DataHandler.getWishlists { (success, dataArray, dropOptionsArray)  in
        if success && dataArray != nil {
            self.shouldAnimateCells = true
            self.dataSourceArray = dataArray as! [Wishlist]
            self.theCollectionView.isHidden = false
            self.theCollectionView.reloadData()
            self.dropOptions = dropOptionsArray as! [DropDownOption]
            self.addButton.isEnabled = true
            self.activityIndicator.stopAnimating()

            // save dataSourceArray in UserDefaults
            if let defaults = UserDefaults(suiteName: UserDefaults.Keys.groupKey) {
                defaults.setDataSourceArray(data: dataArray as! [Wishlist])
                defaults.synchronize()
            } else {
                print("error Main")
            }
        }
    }

3. retrive data in Share Extension (error 2 fires!)

if let defaults = UserDefaults(suiteName: UserDefaults.Keys.groupKey) {
        if let data = defaults.getDataSourceArray() {
            dataSourceArray = data
            defaults.synchronize()
        }else {
            print("error 2")
        }

    } else {
        print("error 1")
    }

UserDefaults + Helpers

extension UserDefaults {

public struct Keys {
    public static let groupKey = "group.wishlists-app.wishlists"

    public static let dataSourceKey = "dataSourceKey"
}



func setDataSourceArray(data: [Wishlist]){
    set(try? PropertyListEncoder().encode(data), forKey: Keys.dataSourceKey)
    synchronize()
}

func getDataSourceArray() -> [Wishlist]? {
    if let data = UserDefaults.standard.value(forKey: Keys.dataSourceKey) as? Data {
        if let dataSourceArray = try? PropertyListDecoder().decode(Array<Wishlist>.self, from: data) as [Wishlist] {
            return dataSourceArray
        }
    }
    return nil
}
}

I can not retrieve the data inside my Share Extension but I have no idea why. Could anyone help me out here?


Solution

  • Your helper function getDataSourceArray() tries to access UserDefaults.standard which is not shared between your host app and the extension app. You need to use the shared container.

    Try to change your function to this:

    func getDataSourceArray() - > [Wishlist] ? {
        if let data = UserDefaults(suiteName: UserDefaults.Keys.groupKey).value(forKey: Keys.dataSourceKey) as ? Data {
            if let dataSourceArray =
                try ? PropertyListDecoder().decode(Array < Wishlist > .self, from: data) as[Wishlist] {
                    return dataSourceArray
                }
        }
        return nil
    }