Introducing Swift Playgrounds - Apple Developer · Exploring with Swift on iPad Developer Tools...

Post on 04-Oct-2020

23 views 0 download

Transcript of Introducing Swift Playgrounds - Apple Developer · Exploring with Swift on iPad Developer Tools...

© 2016 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

Exploring with Swift on iPad

Developer Tools #WWDC16

Session 408

Introducing Swift Playgrounds

Matt Patenaude Playgrounds EngineerMaxwell Swadling Playgrounds EngineerJonathan Penn Playgrounds EngineerIzzy Fraimow Playgrounds Engineer

1024 x 768

1024 x 768

Using Swift Playgrounds

Using Swift PlaygroundsAuthoring for Swift Playgrounds

Using Swift PlaygroundsAuthoring for Swift PlaygroundsGrowing and Exploring

Using Swift Playgrounds

Maxwell SwadlingPlaygrounds Engineer

PlaygroundMarkup

Source Code

CodeCompletion

Undo/Redo

Shortcuts

Live View

Run Button

Documents

Table of Contents

PageNavigation

Library

Tools Menu

Snippets

Images

Files

DemoUsing Swift Playgrounds

Authoring for Swift Playgrounds

Jonathan PennPlaygrounds Engineer

Chapters / Pages

Introduction

Issuing Commands

Chapter: Commands

Introduction

Composing a New Behavior

Chapter: Functions

Chapters / Pages

Introduction

Issuing Commands

Chapter: Commands

Introduction

Composing a New Behavior

Chapter: Functions

Cutscenes

Cutscenes

Glossary

Glossary

Glossary

Editable Regions

Editable Regions

func /*#-editable-code*/ <#funcName#> /*#-end-editable-code*/() {

//#-editable-code Add commands to your function

//#-end-editable-code

}

//#-editable-code Tap to enter code

//#-end-editable-code

Hidden Code

Hidden Code

//#-hidden-code

yourSetupFunction()

//#-end-hidden-code

Configurable Code Completion

Configurable Code Completion

//#-code-completion(everything, hide)

//#-code-completion(currentmodule, show)

//#-code-completion(identifier, show, moveForward(), turnLeft())

“Always-On” Live View

“Always-On” Live View

Hints

Hints

Assessment

Assessment

Assessment

Assessment

// Key/Value Store

import PlaygroundSupport

let store = PlaygroundPage.current.keyValueStore

store["Greeting"] = .string("Hello, WWDC!")

if case let .string(greeting)? = store["Greeting"] {

print(greeting) // "Hello, WWDC!"

}

Resettable

Resettable

Resettable

Resettable

Resettable

Resettable

Documented

apple.com

1024 x 768

DemoAuthoring for Swift Playgrounds

MyFirst.playgroundbook

Contents

Chapter1.playgroundchapterPages

Chapters

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Key Type Value

Root Dictionary

Name String Introduction

LiveViewMode String VisibleByDefault

PosterReference String LiveViewPoster.png

LiveViewEdgeToEdge Boolean YES

PlaygroundLoggingMode String Off

Page Manifest

Name = “Introduction”

LiveViewMode = “VisibleByDefault”

PosterReference = “LiveViewPoster.png”

LiveViewEdgeToEdge = YES

LiveViewEdgeToEdge = NO

PlaygroundLoggingMode = “Off”

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents.swift

// Contents.swift

/*:

Instructions about the page...

*/

//#-hidden-code

import PlaygroundSupport

func say(_ message: String) {

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

proxy.send(.string(message))

}

}

//#-end-hidden-code

say(/*#-editable-code*/"<#Knock, knock!#>"/*#-end-editable-code*/)

// Contents.swift

/*:

Instructions about the page...

*/

//#-hidden-code

import PlaygroundSupport

func say(_ message: String) {

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

proxy.send(.string(message))

}

}

//#-end-hidden-code

say(/*#-editable-code*/"<#Knock, knock!#>"/*#-end-editable-code*/)

// Contents.swift

/*:

Instructions about the page...

*/

//#-hidden-code

import PlaygroundSupport

func say(_ message: String) {

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

proxy.send(.string(message))

}

}

//#-end-hidden-code

say(/*#-editable-code*/"<#Knock, knock!#>"/*#-end-editable-code*/)

// Contents.swift

/*:

Instructions about the page...

*/

//#-hidden-code

import PlaygroundSupport

func say(_ message: String) {

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

proxy.send(.string(message))

}

}

//#-end-hidden-code

say(/*#-editable-code*/"<#Knock, knock!#>"/*#-end-editable-code*/)

// Contents.swift

/*:

Instructions about the page...

*/

//#-hidden-code

import PlaygroundSupport

func say(_ message: String) {

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

proxy.send(.string(message))

}

}

//#-end-hidden-code

say(/*#-editable-code*/"<#Knock, knock!#>"/*#-end-editable-code*/)

// Contents.swift

/*:

Instructions about the page...

*/

//#-hidden-code

import PlaygroundSupport

func say(_ message: String) {

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

proxy.send(.string(message))

}

}

//#-end-hidden-code

say(/*#-editable-code*/"<#Knock, knock!#>"/*#-end-editable-code*/)

// Contents.swift

/*:

Instructions about the page...

*/

//#-hidden-code

import PlaygroundSupport

func say(_ message: String) {

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

proxy.send(.string(message))

}

}

//#-end-hidden-code

say(/*#-editable-code*/"<#Knock, knock!#>"/*#-end-editable-code*/)

Contents

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

ResourcesSources

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

// LiveView.swift

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

// LiveView.swift

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

// LiveView.swift

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

// LiveView.swift

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents

ResourcesSources

Pages

Chapters

Manifest.plistContents.swiftLiveView.swift

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents.swift

In main process

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents.swift

In main processOnly active while running

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents.swift

In main processOnly active while running

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents.swift

In main processOnly active while running

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents.swift LiveView.swift

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

In main processOnly active while running

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents.swift

Separate process

LiveView.swift

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

In main processOnly active while running

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

Contents.swift

Separate processRunning all the time

LiveView.swift

import PlaygroundSupport

let page = PlaygroundPage.current

page.liveView = FaceViewController()

import PlaygroundSupport

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

let message: PlaygroundValue = .string("Knock, knock!")

proxy.send(message)

}

Main Process (Contents.swift)

import PlaygroundSupport

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

let message: PlaygroundValue = .string("Knock, knock!")

proxy.send(message)

}

Main Process (Contents.swift)

import PlaygroundSupport

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

let message: PlaygroundValue = .string("Knock, knock!")

proxy.send(message)

}

Main Process (Contents.swift)

import PlaygroundSupport

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

let message: PlaygroundValue = .string("Knock, knock!")

proxy.send(message)

}

Main Process (Contents.swift)

import PlaygroundSupport

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

let message: PlaygroundValue = .string("Knock, knock!")

proxy.send(message)

}

Main Process (Contents.swift)

import PlaygroundSupport

let page = PlaygroundPage.current

if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {

let message: PlaygroundValue = .string("Knock, knock!")

proxy.send(message)

}

Main Process (Contents.swift)

Sending to the Live View Process

Live View ProxyContents.swift FaceViewController

Sending to the Live View Process

Live View ProxyContents.swift FaceViewController

Sending to the Live View Process

Live View ProxyContents.swift FaceViewController

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func receive(_ message: PlaygroundValue) {

if case let .string(text) = message {

processConversationLine(text)

}

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func receive(_ message: PlaygroundValue) {

if case let .string(text) = message {

processConversationLine(text)

}

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func receive(_ message: PlaygroundValue) {

if case let .string(text) = message {

processConversationLine(text)

}

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func receive(_ message: PlaygroundValue) {

if case let .string(text) = message {

processConversationLine(text)

}

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func receive(_ message: PlaygroundValue) {

if case let .string(text) = message {

processConversationLine(text)

}

}

}

Live View Process (LiveView.swift)

Sending from the Live View Process

Live View ProxyContents.swift FaceViewController

Sending from the Live View Process

Live View ProxyContents.swift FaceViewController?

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func tapped() {

let message: PlaygroundValue = .string("Hello!")

send(message)

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func tapped() {

let message: PlaygroundValue = .string("Hello!")

send(message)

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func tapped() {

let message: PlaygroundValue = .string("Hello!")

send(message)

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func tapped() {

let message: PlaygroundValue = .string("Hello!")

send(message)

}

}

Live View Process (LiveView.swift)

extension FaceViewController: PlaygroundLiveViewMessageHandler {

public func tapped() {

let message: PlaygroundValue = .string("Hello!")

send(message)

}

}

Live View Process (LiveView.swift)

Sending from the Live View Process

Contents.swift FaceViewControllerLive View Proxy

Sending from the Live View Process

Contents.swift FaceViewControllerLive View Proxy

Sending from the Live View Process

Contents.swift FaceViewController?

Live View Proxy

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Main Process (Contents.swift)

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy

class MyClassThatListens: PlaygroundRemoteLiveViewProxyDelegate {

func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,

received message: PlaygroundValue) {

if case let .string(text) = message {

doSomethingWithString(text)

}

}

}

let listener = MyClassThatListens()

proxy?.delegate = listener

Sending from the Live View Process

Contents.swift FaceViewControllerLive View Proxy

Sending from the Live View Process

Contents.swift FaceViewControllerLive View Proxy

Sending from the Live View Process

Contents.swift FaceViewControllerLive View Proxy

// Playground Values

public enum PlaygroundValue {

case array([PlaygroundValue])

case dictionary([String: PlaygroundValue])

case string(String)

case data(Data)

case date(Date)

case integer(Int)

case floatingPoint(Double)

case boolean(Bool)

}

// Key/Value Store

import PlaygroundSupport

let store = PlaygroundPage.current.keyValueStore

store["Greeting"] = .string("Hello, WWDC!")

if case let .string(greeting)? = store["Greeting"] {

print(greeting) // "Hello, WWDC!"

}

1024 x 768Contents.swift

1024 x 768Contents.swift LiveView.swift

Contents

ResourcesSources

Chapter1Pages

Chapters

Introduction

HowDoesItWork

Manifest.plistContents.swiftLiveView.swift

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

Contents

ResourcesSources

Chapter1Pages

Chapters

Introduction

HowDoesItWork

Manifest.plistContents.swiftLiveView.swift

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

EditsContents

ResourcesSources

Chapter1Pages

Chapters

Introduction

HowDoesItWork

Manifest.plistContents.swiftLiveView.swift

Chapter1.playgroundchapter

Introduction.playgroundpage

HowDoesItWork.playgroundpage

developer.apple.com

1024 x 768

DemoGrowing and Exploring

Izzy FraimowPlaygrounds Engineer

SummarySwift Playgrounds

SummarySwift Playgrounds

Touch-focused experience for experimenting with Swift

SummarySwift Playgrounds

Touch-focused experience for experimenting with SwiftRich new document format for creating engaging content

SummarySwift Playgrounds

Touch-focused experience for experimenting with SwiftRich new document format for creating engaging contentPowerful access to iOS SDK

Playgrounds

More Information

https://developer.apple.com/wwdc16/408

Related Sessions

Keynote Bill Graham Monday 10:00AM

Platforms State of the Union Bill Graham Monday 2:30PM

What’s New in Swift Presidio Tuesday 9:00AM

Labs

Swift Open Hours Developer Tools Lab A Tuesday 12:00PM

Swift Open Hours Developer Tools Lab A

Wednesday–Friday 9:00AM

Creating Content for Swift Playgrounds Dev Tools Lab C Wednesday 12:00PM

Xcode Open Hours Developer Tools Labs B Wednesday 3:00PM

Xcode Open Hours Developer Tools Labs C Thursday 9:00AM

Creating Content for Swift Playgrounds Dev Tools Lab C Friday 12:00PM