Running Swift Code in the Cloud

Mariusz WisniewskiMariusz Wisniewski

We are happy to announce that now you can use Swift inside a CodeBox!

Read more to learn why we added it and how you can use it. You can skip the intro, and jump straight to usage examples.

Intro

When Apple open-sourced Swift, we at Syncano discussed what it would mean. We wondered how it would change the software world.

Even though we were not able to come up with one answer (each of us had a different theory), we all agreed that this was an interesting opportunity for us. It was an opportunity to see if we could expand our CodeBoxes with Swift runtime and, if yes, how soon could we ship it?

As all of our CodeBoxes run in Docker containers, we needed to prepare a proper image first.

We started our work in the beginning of December, right after Swift was published on Apple's GitHub page.

We managed to finish our work on Dec 17th. After some more testing, we were ready to add it to our production environment. Now it's finally here and you can play with it yourself!

You can find information on how to install our Docker image on your own machine for testing on Syncano's GitHub.

Usage Examples

Open-Source Swift

The Swift environment you have available using open-source implementation (and inside a CodeBox) is not the same as the one under, for example, iOS.

The most noticeable difference will be with using Foundation. As the authors state:

As Foundation is a work in progress, not all methods and functionality are present. When implementations are completed, this list should be updated to reflect the current state of the library.

You can find the current state of the open-source Foundation library on its status page.

Examples

We have already imported the Foundation library, so you don't have to do it in your CodeBox scripts.

Parsing JSON

This is the exact same code we use internally to convert JSON passed by you to CodeBox as a payload into native objects.

func deserializeJSON(json: NSString) throws -> [String: Any] {  
    let jsonData = json.dataUsingEncoding(NSUTF8StringEncoding)!
    return try NSJSONSerialization.JSONObjectWithData(jsonData,
        options: NSJSONReadingOptions.MutableContainers) as! [String: Any]
}

//these dictionaries are available for you inside CodeBox
let ARGS = try! deserializeJSON("{additional_args}")  
let CONFIG = try! deserializeJSON("{meta}")  
let META = try! deserializeJSON("{config}")  

We define our deserialize function as taking one String object with JSON structure inside and returning a [String: Any] dictionary.

You may notice that we don't handle any errors here. We don't do that because we are in control of the JSON passed. We are sure that whatever is inside {additional_args}, {meta} and {config} is always a valid JSON.

Using a Payload

Here you can see how to use a payload passed to a Swift CodeBox. In this example we will

// Create Enum for more readable code
// Each Enum value will have a String raw value assigned
enum PreferredAnimal : String {  
    case None = "None"
    case Cat = "Cat"
    case Dog = "Dog"
}

// Before we assign an animal to a name, we set the preferred animal to .None - meaning it wasn't chosen yet
var preferredAnimal = PreferredAnimal.None

// We check if firstName and lastName were passed in the payload. 
// If they are not, firstName and lastName are to be equal to nil and the check fails. 
// We also make sure passed values aren't just empty strings.
if let firstName = ARGS["first_name"] as! String? where !firstName.isEmpty,  
   let lastName = ARGS["last_name"] as! String? where !lastName.isEmpty
{
    // We 'calculate', based on the number of characters in the name, 
    // if preferred animal is a cat or a dog
    if (firstName.characters.count + lastName.characters.count) % 2 == 0 {
        preferredAnimal = .Cat
    } else {
        preferredAnimal = .Dog
    }
}

// Now we know what the preference is!
// Print it as JSON
print("{\"preferred\":\"\(preferredAnimal.rawValue)\"}")  

You can test it by typing

{"first_name": "FirstName", "last_name":"LastName"}

into the payload box and then running your code.

Running a CodeBox

Reading the Year Value from a Date

Using NSDate, NSDateComponents and NSCalendar you can read chosen elements from a given date. In the example below, we read and print the current year but you can modify it to also get, for example, a month and a day.

// Get current date and system calendar
let dateNow = NSDate()  
let currentCalendar = NSCalendar.currentCalendar()

// See available values: 
// https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCalendar_Class/#//apple_ref/c/tdef/NSCalendarUnit
// You can specify more flags like that:
// let flags: NSCalendarUnit = [.Second, .Minute, .Hour, .Day, .Month, .Year]
let flags: NSCalendarUnit = [.Month, .Year]  
let dateComponents : NSDateComponents! = currentCalendar.components(flags, fromDate: dateNow)

let year = dateComponents?.year

print("We currently have year \(year!)")  

That's it! You can run your Swift code using Syncano CodeBoxes. Just remember the current limitations of the open-source Foundation.

If you'd like to contribute to it, make sure to visit Foundation GitHub repo.

As always, you can reach us for help at [email protected]. If you have any questions about running Swift -- feel free to ping me on Twitter.

How will you use Swift in a CodeBox? Let us know in comments!

Build powerful apps in half the time

Use our serverless platform to set up your backend in minutes.

Learn more

#ios #developer, #kravmaga learner, dev relations at @syncano. Smash fear, learn anything!