Xcode playgrounds are a delightful way to explore the Swift language — once you get them set up. I admit that I’ve grown to love environments where I can code with simple text files, however, I also love to develop iOS apps and so I find myself digging once again thru the byzantine Xcode GUI. It seems I always forget the magic incantations!

Here are the notes for my future self and other intrepid explorers:

Experimenting with Parse.com in Swift 2, Xcode 7.2, OSX 10.10.5 (Yosemite)

note: cocoapods 0.39.0 has issue with Ruby 2.3 (https://github.com/CocoaPods/CocoaPods/issues/4345) — likely fixed in the 1.0 beta, but I stuck with older ruby and released cocoapod for this exercise.

rvm use ruby-2.2.4
gem install cocoapods

Make a new Xcode project, and add a new Empty file to your project called Podfile (New > File… > Other > Empty), with the following contents:

platform :ios, '8.1'
xcodeproj 'ParsePlayground'
 
use_frameworks!
target :ParsePlayground, :exclusive => true do
  pod 'Parse'
end

back on the command-line:

pod install

This creates a new Xcode workspace, so we need to close the project in Xcode, then re-open Xcode with the file named something ending in .xcworkspace.

This new workspace should have both the original project and a new one called Pods. Now we can create the Playground, by selecting the menu: File > New > Playground… Then we save it in the root of our project directory, then add it to the project with the menu: File > Add Files To “ParsePlayground”

Now this code should compile:

import Parse
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

We want to set needsIndefiniteExecution so that the async commands will work.

I made a new Parse app to experiment, then in the parse docs, in the QuickStart Guide, they set up some sample code already customized with the app ID and client key, it should be something like:

Parse.setApplicationId("abunchofnumbersandletters",
clientKey: "morelettersandnumbers")

Then we can start coding! I made an item class in Parse with a string property “info.” Here some code that worked for me:

let testObject = PFObject(className: "TestObject")
 
testObject["foo"] = "bar"
testObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
print("Object has been saved: (success)")
}
 
var query = PFQuery(className: "item")
var items = try query.findObjects()
print("got some items")
for item in items {
var info = item["info"]
print(" item #(item.objectId!) info:(info)")
}
 
print("not the end... wait for the sync call to finish")

When I run the above code it works fine, but I do get some of the following errors. Not sure why…

Failed to obtain sandbox extension for path=/var/folders/hz/vnvkxt7x4236fp6nqt5zy2wr0000gn/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.experiment-3C8D4B75-8EA0-4BE8-8467-1B06C9B1F881/Library/Caches

I’ve posted the full ParsePlayground project on Github with some notes on how to set up the Parse app if you want to jump right in!

Create a new application (File > New > Project)

Create a Single View Application as usual…

dialog box with 'Single View Application' selected
Create a Single View Application

Name your project:

XCode New Project Dialog box

Fill in project name, organization name, identifier (like com.yourcompany) and for now, unchecking unit tests. I’m experimenting with a new Mightyverse prototype so I filled in:
* PhraseRecorder
* Mightyverse
* com.mightyverse

which created the app identifier: com.mightyverse.PhraseRecorder

It will also create a folder full of files named with your project name and this will also be the name of the app. I don’t like spaces in file paths, so I use camel case with no spaces.

Run the app now and you should see a blank white screen. I usually use iPhone 5 since the screen is small and easy to preview on my laptop. Let’s go to the home screen and see how the project name is used as the app name. (Choose Hardware > Home or shift-command-H)

multiple icons on home screen, new app has truncated name followed by an elipsis

The name I picked was too long so it appears truncated with elipses. This wasn’t the name I wanted the end user to see anyhow. This is easy to fix in XCode 7 (though not very discoverable). Stop the app (using the VCR controls at the top of the XCode window). Then click the little folder icon to see your file listing, then double click on the target name in the middle panel and type a new name.

First item selected in first panel, target in second

Run the app again and… voila! your app has a new name.

After getting started with the basic syntax and some frequently used functions, I needed to learn to write some code.

I enjoyed this nice intro to functions.

myfunction <- function(arg1, arg2, ... ) {
   statements
   return(object)
}

We can put functions (or any code) in a text file and load it from the R command line:

source("mycode.R")

where mycode.R is in the same directory as where I’m running R or a full path to the script.

But then I got stuck in how to transform my data table. As much as I wanted to iterate using loops, I felt that was a very un-R-like solution. I found some good patterns in @xieyihui‘s gory loops post.

If you need to make a string, you can use paste like Ruby’s join method:

> words  words
[1] "one"   "two"   "three"

> paste(words)
[1] "one"   "two"   "three"

> paste(words, collapse="")
[1] "onetwothree"

> paste(words, collapse=",")
[1] "one,two,three"

> paste(words, collapse=", ")
[1] "one, two, three"