Request: view the Swift 2.2 version of the "Making A Mac App Scriptable Tutorial"

@sarah I really appreciate the tutorial. It says it “has been updated for Xcode 8 and Swift 3.” Any chance I could see the original tutorial? The app I’m working with has dependencies that can’t be made to work with Swift 3 and I’m wondering if there are any dramatic differences between the old and new tutorial. I’m having trouble reproducing your example project in Xcode 7.

Hi, glad you liked this tutorial, I enjoyed writing it.

I had a look at the changes made to update to Xcode 8 & Swift 3 and they were mainly to do with Swift 3’s renaming. e.g. NSApplication.sharedApplication() became NSApplication.shared() and other things like that.

However the final project file for the Swift 2 version is still available at https://koenig-media.raywenderlich.com/uploads/2016/05/ScriptableTasks-Final.zip so maybe that will work for you.

If not, please contact me again and share any error messages that you are getting.

Cheers,
Sarah

Thanks! On first glance I’m not seeing where I’m going wrong. I’ll keep looking…

So figuring out what I was doing wrong was sort of like bashing my head against a brick wall until it finally worked. Here’s where I was going wrong and what I did to fix it:

In the example tutorial, you did an excellent job of making clear in ScriptableTasks.sdef under

<cocoa key="tasks"/>

“tasks” is a key that is used in 2 specific places.

  1. In the Task class:
NSUniqueIDSpecifier(containerClassDescription: appDescription, containerSpecifier: nil, key: "tasks", uniqueID: id)
  1. In the AppDelegate extension:
return key == "tasks"

But “tasks” is also found in several other places:

  1. (and 2.) In the AppDelegate extension methods:
  func insertObject(object: Task, inTasksAtIndex index: Int) {
    tasks = dataProvider.insertNewTask(object, atIndex: index)
  }

  func removeObjectFromTasksAtIndex(index: Int) {
    tasks = dataProvider.deleteTask(atIndex: index)
  }

inTasksAtIndex and removeObjectFromTasksAtIndex are created by inserting and capitalizing the “tasks” key.

  1. THE LAST AND MOST IMPORTANT place where the key needs to match is the tasks array variable defined at the top of the AppDelegate:

It MUST BE this:

var tasks: [Task]!  // `tasks` matches on `key = "tasks"` so this WILL WORK
...
  override func application(sender: NSApplication, delegateHandlesKey key: String) -> Bool {
    return key == "tasks"
  }

  func insertObject(object: Task, inTasksAtIndex index: Int) {
    tasks = dataProvider.insertNewTask(object, atIndex: index)
  }

If you were to define it as…

var mytasks: [Task]! // `mytasks` does not match on `key = "tasks"` so it WILL NOT WORK
...
  override func application(sender: NSApplication, delegateHandlesKey key: String) -> Bool {
    return key == "tasks"
  }

  func insertObject(object: Task, inTasksAtIndex index: Int) {
    mytasks = dataProvider.insertNewTask(object, atIndex: index)
  }

IT WILL NOT WORK and the console won’t tell you why so YOU WILL BE COMPLETELY AND UTTERLY CONFUSED!

Happily, if you define it correctly, everything works wonderfully! This was probably obvious to most people but it wasn’t for me so just in case there is anyone out there like me, now you know!

This topic was automatically closed after 166 days. New replies are no longer allowed.