RileyDev
RileyDev

Reputation: 2515

Unable to share data using Shared App Groups for Today Extension

I am trying to create a today extension that displays data from the parent app by using a shared app group container, and then adding the persistent store to a context.

I get no errors but the extension does not seem to be fetching any results. Does anybody have any suggestions where I may be going wrong ?

Heres what I am doing in the extension TodayViewController

class TodayViewController: UIViewController, NCWidgetProviding {

var context: NSManagedObjectContext!

@IBOutlet weak var table: UITableView!
var objectsArray = [Objects]()

override func viewDidLoad() {
    super.viewDidLoad()

    let fileManager = NSFileManager.defaultManager()
    var containerPath = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.com.Company.AppName")

    containerPath = containerPath?.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
    let modelURL = NSBundle.mainBundle().URLForResource("AppName", withExtension: "momd")
    let model = NSManagedObjectModel(contentsOfURL: modelURL!)
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model!)
    do {
        try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: containerPath, options: nil)
    } catch {
     print("yellow")
    }

    context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    context.persistentStoreCoordinator = coordinator


    let moc = context
    let request = NSFetchRequest(entityName: "Objects")
    request.sortDescriptors = [NSSortDescriptor(key: "date", ascending: true)]


    do {
        try
            self.objectsArray = moc.executeFetchRequest(request) as! [Objects]
            print ("objects count \(objectsArray.count)")
    } catch {
        // failure
        print("Fetch failed")
    }

    self.table.reloadData()
}

// MARK: - Table view data source

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    //return sectionsArray.count

    return 1
}


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return self.objectsArray.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
   let cell = table.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell!

   cell.textLabel!.textColor = UIColor.whiteColor()
   cell.textLabel!.text = self.objectsArray[indexPath.row].title

   return cell

}

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) {
    // Perform any setup necessary in order to update the view.

    // If an error is encountered, use NCUpdateResult.Failed
    // If there's no update required, use NCUpdateResult.NoData
    // If there's an update, use NCUpdateResult.NewData

    completionHandler(NCUpdateResult.NewData)
}

}

Upvotes: 4

Views: 1664

Answers (1)

wj2061
wj2061

Reputation: 6885

In Apple's App Extension Programming Guide --Sharing Data with Your Containing App

Even though an app extension bundle is nested within its containing app’s bundle, the running app extension and containing app have no direct access to each other’s containers.

So they wouldn't be able to share data directly,even if you

Add Today Extension as Target Membership for Data model and entities

Instead,they communicated with each other by shared container(App groups) indirectly,which you had already setup in step 2.

enter image description here

So the solution is :

  1. In your Contraning App,create the sql data model in your shared container ,insert data in this database.Adjust your code in todayExtension ,and fetch data.
  2. Or Using NSUserDefaults to share data instead.

like this:

// Create and share access to an NSUserDefaults object
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"com.example.domain.MyShareExtension"];

// Use the shared user defaults object to update the user's account
[mySharedDefaults setObject:theAccountName forKey:@"lastAccountName"];

Upvotes: 3

Related Questions