How to make and publish a Swift playground book for iPad

F9feb45c0a049cccc3e2563f1fe2f869?s=47 sonson
September 01, 2018

How to make and publish a Swift playground book for iPad

F9feb45c0a049cccc3e2563f1fe2f869?s=128

sonson

September 01, 2018
Tweet

Transcript

  1. 1.

    Χϝϥ͔Βͷը૾ΛϦΞϧλΠϜʹ͍͡ΔPlayPixels Tech. Yuichi Yoshida Senior researcher, DENSO IT Laboratory, Inc.

    #iOSDC2018 @sonson_twit © 2014 DENSO IT Laboratory, Inc., All rights reserved. Redistribution or public display not permitted without written permission from DENSO IT Laboratory, Inc. Swift Playgrounds Bookͷ࡞Γํͱ഑Γํ
  2. 2.

    ࣗݾ঺հ • sonson • twitter: sonson_twit • github: sonsongithub •

    portfolio • 2tchɾɾɾଟ෼ɼࣙΊΔ • numsw • iOS11 Programming Book(ൃചத) • ࢓ࣄ(computer vision, machine learning) • ը૾ೝࣝɾݕࡧٕज़ • ࠷ۙ͸σʔλαΠΤϯεతͳ͜ͱ΋
  3. 6.
  4. 8.

    ࠓ೔ͷ͓࿩ • ໨త • iPadʹࣗ෼޷ΈͷSwift coding؀ڥΛ࡞Δ • ͦ͏͍͏؀ڥΛΈΜͳͰެ։͋ͬͯ͠ɼָ͠Ή • ࡞Γํͱެ։ํ๏

    • Appleۘ੡ͷςϯϓϨʔτʹΑΔ࡞ΓํΛ঺հ • ެ։Ͱ͖ΔΜͰ͢Αɼ͜Ε͕ɽ • Χϝϥͷը૾ॲཧΛ͢Δαϯϓϧ • ը૾ॲཧͷࠜװΛ஌ͬͯ΋Β͏
  5. 10.

    ͍͍ͱ͜Ζ • ϝΠϯͷ໨త͸ڭҭΒ͍͠ • Ͱ΋Ͷ͐ɾɾίϯςϯπ࡞Δͷେม • iPadͰಈ͘ʂʂʂ • Ͳ͜Ͱ΋ίʔυ͕ॻ͚Δ •

    ͓खܰɼ͔ͬ͜Α͘σϞͰ͖Δ • ͲΜͲΜਐԽ͍ͯ͠Δ • Χϝϥ͕࢖͑ΔΑ͏ʹͳͬͨʂ • Bluetooth͕࢖͑ΔΑ͏ʹͳͬͨʂ
  6. 14.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift
  7. 19.

    Swift Playgrounds Author Template • ΞϓϦͱͯ͠BookΛಈ͔͠ɼσόοά͠΍͘͢ • Bluetooth౳ͷUIΛΤϛϡϨʔτ • ϏϧυεΫϦϓτ΋ࠐΈ

    • σόοά • iOS12ͰSwift PlaygroundsͰNSLogΛ࣮ߦͯ͠΋Կ ΋දࣔ͞Εͳ͍ɾɾɾɾ • ͜ͷςϯϓϨʔτ͕།Ұͷ։ൃ؀ڥɾɾɾɾ
  8. 24.
  9. 25.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift
  10. 26.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift ຊମ
  11. 27.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift ϖʔδ ࠷খ୯Ґ
  12. 28.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift ֤ϖʔδͷઃఆ
  13. 29.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift ຊͷߏ੒
  14. 30.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift Ϧιʔε
  15. 31.

    Playgroundbookͷߏ੒ ├── Chapters │ └── Chapter1.playgroundchapter │ ├── Manifest.plist │

    └── Pages │ ├── Basic.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ ├── Binarize.playgroundpage │ │ ├── Contents.swift │ │ ├── LiveView.swift │ │ └── Manifest.plist │ └── Filter.playgroundpage │ ├── Contents.swift │ ├── LiveView.swift │ └── Manifest.plist ├── Manifest.plist ├── PrivateResources │ ├── Base.lproj │ │ └── LiveView.storyboard │ ├── en.lproj │ │ └── ManifestPlist.strings │ └── icon.png └── Sources ├── LiveViewController.swift └── LiveViewSupport.swift Ұ൪େ੾ ڞ௨ͷΫϥεͱ͔
  16. 34.

    Contents.swift • ίʔσΟϯάʹؔ͢Δίϝϯτ΍ώϯτɼεέϧτϯίʔυ • ษڧͱͯ͠ͷίϯςϯπ͸ͪ͜Β͕ओ //#-hidden-code import UIKit import PlaygroundSupport

    //#-end-hidden-code func process(input: UnsafePointer<CUnsignedChar>, output: inout [CUnsignedChar], width: Int, height: Int, bytesPerPixel: Int) { //#-editable-code // write your own code //#-end-editable-code } //#-hidden-code class Listener: PlaygroundRemoteLiveViewProxyDelegate { func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy, received message: PlaygroundValue) { // handle message from LiveViewController } } let listener = Listener() if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy { proxy.delegate = listener } //#-end-hidden-code
  17. 43.

    ૹड৴Ͱ͖Δܕ public enum PlaygroundValue { case array([PlaygroundSupport.PlaygroundValue]) case dictionary([String :

    PlaygroundSupport.PlaygroundValue]) case string(String) case data(Data) case date(Date) case integer(Int) case floatingPoint(Double) case boolean(Bool) }
  18. 45.

    ड৴͚͕ͩҟͳΔ $POUFOUͷϓϩηε class Listener: PlaygroundRemoteLiveViewProxyDelegate { var pixelBuffer24bit: [CUnsignedChar]? func

    remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy, received message: PlaygroundValue) { // handle a message } func remoteLiveViewProxyConnectionClosed(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy) { } } let listener = Listener() if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy { proxy.delegate = listener }
  19. 51.

    LiveViewTest.app • UIApplication౳Λվ଄ʁ • LiveViewControllerͷಈ࡞֬ೝ༻ͷΞϓϦ • Swift Playgroundsઐ༻ͷUIͷςετ • ͦͷͨΊͷBluetoothͳͲͷϑϨʔϜϫʔΫ

    • Contents.swiftͷ୅ཧίʔυͷ࣮૷͕ඞཁ ࢖͏΂͖ɽσόοάͰࢮͶΔ #if LiveViewTestApp // γϛϡϨʔλͰಈ͔͢ͱ͖͸ɼϝιουΛ௚Ͱୟ͖ɼContents.swiftͷ୅ΘΓΛ࣮ߦ self.update(value) #else // PlaygroundͰಈ͔͢ͱ͖͸ɼproxyܦ༝ͰContents.swiftʹσʔλΛૹΔ self.send(value) #endif
  20. 59.

    feed { "title": "sonson", "publisherName": "Yuichi Yoshida", "feedIdentifier": "com.sonson.playground", "contactURL":

    "mailto:hoge@hoge.com", "formatVersion": "1.0", "documents": [ { "title": "PlayPixels", "overviewSubtitle": "To be written.", "detailSubtitle": "αϒλΠτϧৄࡉ", "description": "ৄ͍͠આ໌", "contentIdentifier": "com.sonson.playground.PlayPixels", "contentVersion": "1.0", "url": "https://sonson.jp/playgrounds/playpixels/PlayPixels.playgroundbook.zip", "publishedDate": "2018-05-18T12:00:00+00:00", "lastUpdatedDate": "2018-05-18T12:00:00+00:00", "thumbnailURL": "playpixels/thumbnail.png", "bannerImageURL": "playpixels/thumbnail.png", "additionalInformation": [ { "name": "Languages", "value": "English" } ], "previewImageURLs": [] } ] }
  21. 60.

    खॱ • ެ։ͷͨΊͷjsonϑΝΠϧ(feed)Λ࡞Δ • BookΛෳ਺ݸऩΊΒΕΔ • ϋϚΔϙΠϯτ • λΠτϧͱ໊લ͕Ұக •

    λΠτϧͱղౚޙͷ໊લ͕Ұக • identifier͕Ұக • feedʹࢦఆͨ͠ύεʹzipͰݻΊͨbookϑΝΠϧΛஔ͘ ├── feed.json ├── index.html └── playpixels ├── PlayPixels.playgroundbook.zip └── thumbnail.png
  22. 73.

    ৞ΈࠐΈԋࢉʔϑΟϧλ ೖྗը૾ ग़ྗը૾       

                     
  23. 74.

    ৞ΈࠐΈԋࢉʔϑΟϧλ ೖྗը૾ ग़ྗը૾       

                               º
  24. 75.

    ৞ΈࠐΈԋࢉʔϑΟϧλ ೖྗը૾ ग़ྗը૾       

                      
  25. 76.

    ৞ΈࠐΈԋࢉʔϑΟϧλ ೖྗը૾ ग़ྗը૾       

                       
  26. 77.

    ৞ΈࠐΈԋࢉʔϑΟϧλ ೖྗը૾ ग़ྗը૾       

                        
  27. 78.

    ৞ΈࠐΈԋࢉʔϑΟϧλ ೖྗը૾ ग़ྗը૾       

                          ϑΟϧλͷαΠζͰ ͪΐͬͱখ͘͞ͳΔ
  28. 81.

    ྲྀߦΓͷCNN Y. Lecun, L. Bottou, Y. Bengio and P. Haffner,

    "Gradient-based learning applied to document recognition," in Proceedings of the IEEE, vol. 86, no. 11, pp. 2278-2324, Nov. 1998. ͜ͷॏΈΛػցֶशͰಘΔ
  29. 82.

    ·ͱΊ • Swift playgroundsͷָ͠͞ • Swift Playgrounds Author TemplateΛ࢖͓͏ •

    Bookͷجຊ • Proxyϕʔεͷϓϩάϥϛϯά • Feedͷઃఆ • ެ։͸ɼPlayground.appͰͰ͖Δʂ • PlayPixelsͰֶͿɼը૾ॲཧͷجຊ