Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to make and publish a Swift playground book for iPad

sonson
September 01, 2018

How to make and publish a Swift playground book for iPad

sonson

September 01, 2018
Tweet

More Decks by sonson

Other Decks in Programming

Transcript

  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. ࣗݾ঺հ • sonson • twitter: sonson_twit • github: sonsongithub •

    portfolio • 2tchɾɾɾଟ෼ɼࣙΊΔ • numsw • iOS11 Programming Book(ൃചத) • ࢓ࣄ(computer vision, machine learning) • ը૾ೝࣝɾݕࡧٕज़ • ࠷ۙ͸σʔλαΠΤϯεతͳ͜ͱ΋
  3. ࠓ೔ͷ͓࿩ • ໨త • iPadʹࣗ෼޷ΈͷSwift coding؀ڥΛ࡞Δ • ͦ͏͍͏؀ڥΛΈΜͳͰެ։͋ͬͯ͠ɼָ͠Ή • ࡞Γํͱެ։ํ๏

    • Appleۘ੡ͷςϯϓϨʔτʹΑΔ࡞ΓํΛ঺հ • ެ։Ͱ͖ΔΜͰ͢Αɼ͜Ε͕ɽ • Χϝϥͷը૾ॲཧΛ͢Δαϯϓϧ • ը૾ॲཧͷࠜװΛ஌ͬͯ΋Β͏
  4. ͍͍ͱ͜Ζ • ϝΠϯͷ໨త͸ڭҭΒ͍͠ • Ͱ΋Ͷ͐ɾɾίϯςϯπ࡞Δͷେม • iPadͰಈ͘ʂʂʂ • Ͳ͜Ͱ΋ίʔυ͕ॻ͚Δ •

    ͓खܰɼ͔ͬ͜Α͘σϞͰ͖Δ • ͲΜͲΜਐԽ͍ͯ͠Δ • Χϝϥ͕࢖͑ΔΑ͏ʹͳͬͨʂ • Bluetooth͕࢖͑ΔΑ͏ʹͳͬͨʂ
  5. 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
  6. Swift Playgrounds Author Template • ΞϓϦͱͯ͠BookΛಈ͔͠ɼσόοά͠΍͘͢ • Bluetooth౳ͷUIΛΤϛϡϨʔτ • ϏϧυεΫϦϓτ΋ࠐΈ

    • σόοά • iOS12ͰSwift PlaygroundsͰNSLogΛ࣮ߦͯ͠΋Կ ΋දࣔ͞Εͳ͍ɾɾɾɾ • ͜ͷςϯϓϨʔτ͕།Ұͷ։ൃ؀ڥɾɾɾɾ
  7. 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
  8. 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 ຊମ
  9. 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. 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. 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. 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. 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. 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
  15. ૹड৴Ͱ͖Δܕ 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) }
  16. ड৴͚͕ͩҟͳΔ $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 }
  17. 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
  18. feed { "title": "sonson", "publisherName": "Yuichi Yoshida", "feedIdentifier": "com.sonson.playground", "contactURL":

    "mailto:[email protected]", "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": [] } ] }
  19. खॱ • ެ։ͷͨΊͷjsonϑΝΠϧ(feed)Λ࡞Δ • BookΛෳ਺ݸऩΊΒΕΔ • ϋϚΔϙΠϯτ • λΠτϧͱ໊લ͕Ұக •

    λΠτϧͱղౚޙͷ໊લ͕Ұக • identifier͕Ұக • feedʹࢦఆͨ͠ύεʹzipͰݻΊͨbookϑΝΠϧΛஔ͘ ├── feed.json ├── index.html └── playpixels ├── PlayPixels.playgroundbook.zip └── thumbnail.png
  20. ৞ΈࠐΈԋࢉʔϑΟϧλ ೖྗը૾ ग़ྗը૾       

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

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

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

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

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

                          ϑΟϧλͷαΠζͰ ͪΐͬͱখ͘͞ͳΔ
  26. ྲྀߦΓͷ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. ͜ͷॏΈΛػցֶशͰಘΔ
  27. ·ͱΊ • Swift playgroundsͷָ͠͞ • Swift Playgrounds Author TemplateΛ࢖͓͏ •

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