├── assets
├── images
│ ├── TDD.png
│ ├── DI-1.png
│ ├── DI-2.png
│ ├── DI-none.png
│ ├── RunStep1.png
│ ├── RunStep2.png
│ ├── repl-p.png
│ ├── survey.jpg
│ ├── lldb-ex3-e.png
│ ├── lldb-ex3-v.png
│ ├── repl-enter.png
│ ├── vary-lang.png
│ ├── Coordinator0.png
│ ├── Coordinator1.png
│ ├── Coordinator2.png
│ ├── Coordinator3.png
│ ├── InlineDisplay.png
│ ├── kickstarter.jpg
│ ├── repl-example1.png
│ ├── repl-return.png
│ ├── TodayPlayground.gif
│ ├── repl-injection.png
│ ├── BuildTimeFramework.png
│ ├── BuildTimeWholeApp.png
│ ├── RealArchitecture.jpg
│ ├── SimpleArchitecture.jpg
│ ├── TargetMembership.png
│ ├── lldb-breakpoint1.png
│ ├── lldb-breakpoint2.png
│ ├── lldb-ex3-call-vm.png
│ ├── lldb-ex3-inject-vm.png
│ ├── playground-error.png
│ ├── repl-call-function.png
│ ├── SwiftUI-preview-Text.png
│ ├── lldb-ex3-breakpoint.png
│ ├── lldb-ex3-inject-vm1.png
│ ├── lldb-ex3-inject-vm2.png
│ ├── lldb-ex3-inject-vm3.png
│ ├── PartitionedArchitecture.jpg
│ ├── SwiftUI-preview-issue.png
│ ├── cocoa-touch-framework.png
│ ├── IdealPartitionedArchitecture.jpg
│ ├── SwiftUI-preview-NSLocalizedString.png
│ ├── SwiftUI-preview-issue-framework.png
│ ├── SwiftUI-preview-issue-main-scheme.png
│ └── repl-breakpoint-call-injected-function.png
├── profile
│ ├── cj.png
│ ├── LINE.png
│ ├── MENU.png
│ ├── BobMarley.png
│ ├── LINE-SDK.png
│ ├── MamiLove.png
│ ├── LINE-TODAY.png
│ ├── Profile.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
│ └── SlidesQRCode.svg
├── code
│ └── DemoLLDB
│ │ ├── DemoLLDB
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── AppDelegate.swift
│ │ └── ViewController.swift
│ │ └── DemoLLDB.xcodeproj
│ │ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── DemoLLDB.xcscheme
│ │ └── project.pbxproj
└── charts
│ ├── DI.xml
│ ├── Simple Architecture.xml
│ └── Coordinator.xml
├── .gitignore
├── README.md
├── index.html
├── theme.css
└── slides.md
/assets/images/TDD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/TDD.png
--------------------------------------------------------------------------------
/assets/profile/cj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/profile/cj.png
--------------------------------------------------------------------------------
/assets/images/DI-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/DI-1.png
--------------------------------------------------------------------------------
/assets/images/DI-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/DI-2.png
--------------------------------------------------------------------------------
/assets/profile/LINE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/profile/LINE.png
--------------------------------------------------------------------------------
/assets/profile/MENU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/profile/MENU.png
--------------------------------------------------------------------------------
/assets/images/DI-none.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/DI-none.png
--------------------------------------------------------------------------------
/assets/images/RunStep1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/RunStep1.png
--------------------------------------------------------------------------------
/assets/images/RunStep2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/RunStep2.png
--------------------------------------------------------------------------------
/assets/images/repl-p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/repl-p.png
--------------------------------------------------------------------------------
/assets/images/survey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/survey.jpg
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-e.png
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-v.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-v.png
--------------------------------------------------------------------------------
/assets/images/repl-enter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/repl-enter.png
--------------------------------------------------------------------------------
/assets/images/vary-lang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/vary-lang.png
--------------------------------------------------------------------------------
/assets/profile/BobMarley.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/profile/BobMarley.png
--------------------------------------------------------------------------------
/assets/profile/LINE-SDK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/profile/LINE-SDK.png
--------------------------------------------------------------------------------
/assets/profile/MamiLove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/profile/MamiLove.png
--------------------------------------------------------------------------------
/assets/images/Coordinator0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/Coordinator0.png
--------------------------------------------------------------------------------
/assets/images/Coordinator1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/Coordinator1.png
--------------------------------------------------------------------------------
/assets/images/Coordinator2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/Coordinator2.png
--------------------------------------------------------------------------------
/assets/images/Coordinator3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/Coordinator3.png
--------------------------------------------------------------------------------
/assets/images/InlineDisplay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/InlineDisplay.png
--------------------------------------------------------------------------------
/assets/images/kickstarter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/kickstarter.jpg
--------------------------------------------------------------------------------
/assets/images/repl-example1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/repl-example1.png
--------------------------------------------------------------------------------
/assets/images/repl-return.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/repl-return.png
--------------------------------------------------------------------------------
/assets/profile/LINE-TODAY.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/profile/LINE-TODAY.png
--------------------------------------------------------------------------------
/assets/images/TodayPlayground.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/TodayPlayground.gif
--------------------------------------------------------------------------------
/assets/images/repl-injection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/repl-injection.png
--------------------------------------------------------------------------------
/assets/images/BuildTimeFramework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/BuildTimeFramework.png
--------------------------------------------------------------------------------
/assets/images/BuildTimeWholeApp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/BuildTimeWholeApp.png
--------------------------------------------------------------------------------
/assets/images/RealArchitecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/RealArchitecture.jpg
--------------------------------------------------------------------------------
/assets/images/SimpleArchitecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/SimpleArchitecture.jpg
--------------------------------------------------------------------------------
/assets/images/TargetMembership.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/TargetMembership.png
--------------------------------------------------------------------------------
/assets/images/lldb-breakpoint1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-breakpoint1.png
--------------------------------------------------------------------------------
/assets/images/lldb-breakpoint2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-breakpoint2.png
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-call-vm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-call-vm.png
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-inject-vm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-inject-vm.png
--------------------------------------------------------------------------------
/assets/images/playground-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/playground-error.png
--------------------------------------------------------------------------------
/assets/images/repl-call-function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/repl-call-function.png
--------------------------------------------------------------------------------
/assets/images/SwiftUI-preview-Text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/SwiftUI-preview-Text.png
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-breakpoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-breakpoint.png
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-inject-vm1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-inject-vm1.png
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-inject-vm2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-inject-vm2.png
--------------------------------------------------------------------------------
/assets/images/lldb-ex3-inject-vm3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/lldb-ex3-inject-vm3.png
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/assets/images/PartitionedArchitecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/PartitionedArchitecture.jpg
--------------------------------------------------------------------------------
/assets/images/SwiftUI-preview-issue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/SwiftUI-preview-issue.png
--------------------------------------------------------------------------------
/assets/images/cocoa-touch-framework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/cocoa-touch-framework.png
--------------------------------------------------------------------------------
/assets/images/IdealPartitionedArchitecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/IdealPartitionedArchitecture.jpg
--------------------------------------------------------------------------------
/assets/images/SwiftUI-preview-NSLocalizedString.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/SwiftUI-preview-NSLocalizedString.png
--------------------------------------------------------------------------------
/assets/images/SwiftUI-preview-issue-framework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/SwiftUI-preview-issue-framework.png
--------------------------------------------------------------------------------
/assets/images/SwiftUI-preview-issue-main-scheme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/SwiftUI-preview-issue-main-scheme.png
--------------------------------------------------------------------------------
/assets/images/repl-breakpoint-call-injected-function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eJamesLin/FastAppDevCycle/HEAD/assets/images/repl-breakpoint-call-injected-function.png
--------------------------------------------------------------------------------
/assets/profile/Profile.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/assets/profile/Profile.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct Profile {
4 | let name = "CJ Lin"
5 | var identity = "iOS Developer"
6 | var company = "LINE"
7 | var blog = "https://ejameslin.github.io"
8 | var line = "ejameslin"
9 | var twitter = "@eJamesLin"
10 | }
11 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## User settings
2 | xcuserdata/
3 |
4 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
5 | *.xcscmblueprint
6 | *.xccheckout
7 |
8 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
9 | build/
10 | DerivedData/
11 | *.moved-aside
12 | *.pbxuser
13 | !default.pbxuser
14 | *.mode1v3
15 | !default.mode1v3
16 | *.mode2v3
17 | !default.mode2v3
18 | *.perspectivev3
19 | !default.perspectivev3
20 |
21 | ## Gcc Patch
22 | /*.gcno
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Slides at GitHub page
2 | - https://ejameslin.github.io/FastAppDevCycle
3 |
4 | ### About
5 | - 大型專案生存守則 - 10x 加速開發技巧
6 | > 在大型專案中血與淚的經驗,改幾行 Code,Incremental Build 也要數十分鐘,只能去喝杯咖啡? 除了加速 Build Time 之外的另一個思路:不要 Build & Run。 分享有哪些技巧能更快看到程式碼改動結果,會遇到的問題與解法。
7 | - The Survival Guide of Building Huge App - 10x Faster Dev/Verification Cycle
8 | - This is the slide presented at [iPlayground2019](https://iplayground.io/2019)
9 |
10 | ### File
11 | - [Markdown Format Slides](slides.md)
12 | - [Demo code](assets/code)
13 |
14 | ### Running at Local
15 | - Start local server by
16 | ```
17 | python -m SimpleHTTPServer 4000
18 | ```
19 | - or by
20 | ```
21 | ruby -rwebrick -e'WEBrick::HTTPServer.new(:Port => 4000, :DocumentRoot => Dir.pwd).start'
22 | ```
23 | - Then open: http://localhost:4000
24 |
25 | ### Special Thanks
26 | - The slides is made by Markdown using [remark](https://github.com/gnab/remark)
27 | - The css theme is forked from [Blue Standard Theme](https://github.com/sfc-arch/remark-theme)
28 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/assets/charts/DI.xml:
--------------------------------------------------------------------------------
1 | 7VtNc+I4EP01HKFs+QuOhExmD7tVqcnO7sxpS5Fl0Ea2iCwG2F+/ErbAlp3CITaYFDkEqyV/9XvuVj/LA2cWb75yuFz8wUJMB8AKNwPnfgDAxAHyvzJsM4PnW5lhzkmYmeyD4Yn8h3OjHrYiIU5LAwVjVJBl2YhYkmAkSjbIOVuXh0WMls+6hHNcMTwhSKvWv0koFpl1DIKD/TdM5gt9ZtufZD0x1IPzO0kXMGTrgsn5MnBmnDGRbcWbGabKd9ov2X4Pb/TuL4zjRDTZIcSv/75Gq2/f//z+6vwk1Bq/PA2d/OJ+QbrK7zi/WrHVLuBslYRYHcUaOHfrBRH4aQmR6l1LzKVtIWIqW7bcTAVnL3jGKOPSkrAE743af4G05GfFXODNm/dj770k2YVZjAXfyiF6B33tObPcsZe11wecfO38RRGjIB8Ic27M98c+uE9u5B58hzfB5Hq96ZW96egHsOhNq86bGob2vTm+Xm+6ZW/a1uW96V/GmxGhVA8aACf08Dh0u/GyB6pe3vO45GXQlZftGif7VCg/MHlTRW/7ryumO4bpLvFN5QDpgM2hU27N1e9fBK/1kZ65ts7krpxRirnukxednSgb8DGEDeiiKAIIVZBXoPrPvue3BKpvPDo1oNp1Yd3v7MnpCNNpAulWEJR+HvD2T1tvwHM6Au/r9POg5vbukXOP5yqchFM1v5ctRGGaElT2JN4Q8aOw/VMBMPLy1v0mx2PX2OqGDKfbH8VGYS/VPOy2a+n9sovDYaWUMBCQN8BWHOHjCURAPsfiWFCqIlpAzKsBTNs4plCQX+XLrUMxP8MjI7uH5Y0Y7bgGEbLbzPcq1iTGgYARL8DEOFDmh8qBdqTa3/bpPPNa4NmJnDmFny3yDDTkmXNJnrnGBA+Y87amPHOAEeHMyNUxzxrMvdMFXKpNEu8UiSLFVHAnCNIpJfNE2gRbFqy/w2dMH1lKBGGq95kJwWI5gKqOO4he5rsUVE4r8k8O2Z1smi4z5URRDOpGRDYqad3l13O/EEJJLlPlG/CAwsQdEcSSiMjkxkdInhE8hFBA+aPsafaLFOnxMOIYD7XZtl2VM4eIszT9B3j+0Abj0TKZtzEBMcpYe1JTEtQQtrOySwe4W0XQWkXgXHx6YndV5lVKggOyj5wJhhit9nwepM3yoQdI34q/k8uIHqBXV/1dXx1xvGiwGs7m7OagXqaS8NqqJNwzVxJ2XSlxExrKEcLvX3xvMDO/gghxktLQtATMqH2pCOGZEcI6MUKY5HO9M0eIoD2qWadQzX4f1UKYLnbRxL4U7y6amfYJxHy59F7eeYaI4QZn5l2D16g1YsNHZIV6wWK/AKLELmtQ99ZQqyHxZq6WlYwIS4NRTFI0QoQjiusylWXNZpZl5Lb8vWQLycsJ3DKO1riSvOpyV3fvGutWG9ykhY9IC5536QmJPtlNWuhWWugB0mcTka4fPVNa6AF6dcLQ9RUOx2drk4azNe393koLgTnvOlVaCMyM3vEEDtzWMLxfWuhBhPgcixiOv0luvGTB6VmEMKWFwHwLeKq04I/PHCHaWMfQM2mhRd71LTOZ0kJgKlGnSguBqY11zbs6SauNzPQNw1DhIZiixkZwiIRuRhzGeM34S9PkJZOKGBxfulyjGsBcv1CrGGTZWxU2YhKGOzGiLiWWk2YLOc6c0bg1ixuA/rjhg6sbZPPwaUrGl8P3Pc6X/wE=
--------------------------------------------------------------------------------
/assets/charts/Simple Architecture.xml:
--------------------------------------------------------------------------------
1 | 7Zxdc+I2FIZ/DZd0/G1zyZJNs9NJZ9u0s3vXEbYw3hjLFSKQ/vrKIOEvGQNBWKzJxcIeyZJ9nnNk+T1OBuZksfkVg3T+jAIYDwwt2AzMh4Fh6K49oh+Z5X1nsR1tZwhxFLBOueEl+g8yI++2igK4LHUkCMUkSstGHyUJ9EnJBjBG63K3GYrLs6YghDXDiw/iuvVbFJD5zuoZbm5/glE45zPrDrvgBeCd2ZUs5yBA64LJ/DwwJxghsvu22ExgnDmP+2V33GND6/7EMEzIMQeg7/9Y0IZ/PH17Dodk/Nvbj5E+dNnZvoF4xa6YnS155y4IMVqlrBvEBG5EjgdT3l2rn5i+v1waJxAtIMHvtAsbyGNH8Ajh6Ne5v12N2eYFX5s8lABjHO6Hzt1AvzBPnOIVV+AVJ6bzfpohelFF9zj/rhBvGC638TumHagDNnkj/RayT7BI6Zdkusw+aL6sYhrebPApLnSMd5+Puxm5ucKGokkCmF2LRpvX84jAlxT4WeuaJiS1zcmCXvuDnp1iFMcTFCO8PdYMAPRmPrUvCUavsNDi+B6czmgLiKMwobYYzvLpBUFQhH0gzuohwJjrnnEcc931ZDH3rsT8EQKywjl0mYhns5nhCxEHztSxnSsito7Mal2TldWOIYkwI0rbx1KgXp4JH8a0SkuvY/1i1yjphoCStKXXMRshLVOQXAJScXHdjak0JMO1ORWFMFnSMU1uC5Olu8pBsiUteH9h4L9GSUg7PIEkiCG+rXXPcMvrnqFp3cNyJMF6AHRzDpZZSj2DhD6v3BgsS1cQlqwHhN8hWSP8mrHaPhrcFqrqfkIJVM37+kvdqR5u605l256CGwqREHGJjJqgZBaFt5VHtfsTFyQ6w+NqkrLo72V2P9LGvk89T24rkWrLXfeYdElZ9CcEcUTej00j6mlShlAWIBKUwIpawUxcjvApGRoZ5qeMW+SDeMwaFlEQZNMIqZfjQl5+CsQMQwTakgXaE+VjBcKVddtR57Kt1bxI3WXbs/LA08QRoI5sa8la8foi27Yg7l62tQxJhNWVbZuYqCvbWv2TbVsgKSnbWv2TbVswKSjbWr2VbVtTSj15yeqtbNuaWArC6qlse+J+QglU/ZNtWygpKdtavZJtT70/da4H2r2UbU9d7rrHJBIxKr6DSTDO3mcd7KXSmrrKX1C1RMqBRn8mk71fYVB77/VMrxa8Zgucxm0YxoBEb+VJRZ5kM3xF0Xb94LnllKGZdgXGEq2wD9lROY/WgarjEIBDSGrjbLnur/oDqEVqxh11kZCluZdBXR3o2qhFD9t31EVCNt/mfRR1daBroxY9st9RFwnp/LV+Xjtw9PNQO6OWgWSzFj3x31kfYm24Z6a141UHMq7L+uOPN6Yh2j9/CSDIZn/EYAGZdPAVYBKRCCV9qbK37dOdMvyhzuAXgtjSBVEsr+p+xD5ddtV9uC+/KVN3N2QJ1v2tuzfEgDp1d6O5knSvu18Acfd1d1laucJl98Mrr4Jld/kiuXJV98OMlKy66801wp+26n4Yk4JVd13Weqd+1b0tpdSrDuqyfllb/ap7W2IpCEtWjVD1qvtp2wkVUPHJ+lR1P0xJyaq7IWv5U7PqfuL9qfNyrtm84P3MVfcTl7vOMdnN7yx/TNx9iRZpvH3ATdPsX+xnPve3619PlN2WWBiVq3VDvmspxIJpCWLhDGWX/jf/G1u7ukD+l8rMz/8D
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/assets/charts/Coordinator.xml:
--------------------------------------------------------------------------------
1 | 7Vxbc+I2FP41zLQPML4KeASStJ3p7mYmO812XzrCFkazxqKy2EB/fSUsgW1kYsAGE8gL1pEs2d/5fHQujlv2aLb8jcL59BPxUdiyDH/Zsh9almU6PYv/CMkqkfTNbiIIKPbloK3gBf+HpNCQ0gX2UZwZyAgJGZ5nhR6JIuSxjAxSSt6ywyYkzK46hwHaEbx4MNyVvmKfTRNpz+pu5b8jHEzVyiboJz0zqAbLO4mn0CdvKZH92LJHlBCWHM2WIxQK8BQuyXlPBb2bC6MoYmVOoF+88ZB9evpj5JGBZc8WI+i15W38hOFC3rC8WLZSCFCyiHwkJjFa9vBtihl6mUNP9L5xnXPZlM1C3jL5Ycwo+YFGJCSUSyIS8WFDuQaiDC0LL97cQMK5hMgMMbriQ+QJva7RcZOTJJEcW07ytlWLq8CfplXSlQqAkgrBZvYtWvxAAqYH73PkTr+3PwP83Xj99vr165cvUdB2SqAXcPjmBXerxUQSGY7VDMZ+YBS9JCzqZlOoANfdRcXq14aKdT5OpSHdr6I80IWAmu4ugI5xTgCt3tG0OgyD8mRbZY1yGhtLh41bGzZ9DTYg5OsOJ4SjkAYJ/LsgqqMdr3eWAR/AEVtuO/lRIH5HhFAfR5BxkskJ+QUmcyYjTiPxBIehonDLsieTieV5O+TmPT4YAxeUZ/iGLaUZDrIWw95VqqsjPKhLp+oCKtfpMyUcdvTX6Bwa9V3U8x2dRnvW2Aa1arSX1ajZ31Wp6Z5VpaZGpTmwUeQPhIPGW14I4xh7WXw5SHT1TeiiY7mq/bfUzbrxsMy0VrJ1IMwM0gDtG6j4ifyMq7irjfQTpEFbySgKIcM/sw6mTgVyhWeC10+BooLZy2i7n5shJgvqIXlS2h/Mz9PPscbKsSEBZmeiNSE2d30CR3R+QjWmPJoQOkuGbGzAAwpRABlqWfxyjUcfM01XOTPBn0pWwkVJGwgpgiEOIkF4Tk3E5UPxjGMebQxkxwz7vlhGa3yy5qk+a7LrATl93S5fm/WwK7AeS8wS4wEc2RS2o210DB6BJoKt/RCNVarxjCjm9yJUdAzWySN4RSYl5xKYvZxqS9uULthrm+o2KU6hSYnnMDrepMRTzjTB92SyMd3nYiRL3ZjtUMzReJOmeVbj4dbEAV/uEp1CVVeyCvZf+EIeEztUrSv9wjt/vXXaqt68B62hsaXNAtRGY1CTd5TxfD56YOQ4jYuMSuQMa4uMtk5Rt5v2ipTDdDmHSOV13g/GQKM8Jwfk89L9rhIc6jw5OS/MMo38VHX7T7rMY4X+U5HtueWtxymx9Zhn3Xqc4/PPlZU1TMfKPVdAk5c/c2FDl3s+ZaM8qbBxuI9z8cKGsrmVFTaKMLjCwoary5jedGFjw5arLWy4dWU4r9R/P1yjjStsuFWkJmsubChA3vWlFT8b4kt/lMKGW5yFvBc2qnO1j7Amly5suMVJnXt+ul4KNCY/DUqUxmuPrnIvjTkaVM4cXAGdr3Sp4AoUId3g4AqU8EwOCa4KMbjC4ArUtyNfaXC1YcvVBleguM53k8HV4RptXHAFdO5Rw4IrBfO7wZXi5z24qjS4Arr62T24qtqzPsKaXDq4AiXKFo18a0xh/W6RtGkm5YO8NQZ0dZ17VH4O29GYqFz929T9rbGbfWvs8C3vom+Naf+ds64iYjNjopP+o7Rv5HJgXWfXBtUV/miVp8uAfew3/k5SoJlPSVxeg7oUXBUafFk7EuUUV9bFVcfr2Ljj7nduN0F1JqLubALsvTF1zl3V5rTTvu8+y5YOu4sfogsG2VlKApV5PNgl3iTY1ExmbqbqnGItjrqMaY5p8RTOxSGerb+hkCZZfrdmZJ6S/gnHKHwmMWaYiN4xYYzwyHsYio4h9H4Ea/OTzXzyPz5kvdggniffehAkg6oxwUthsIbyeh6mjImPRAwENtaT50dOB3s8ysfcsNGOx1e0nnzIIP8R8jj5FR4HRe0JRaitxKYA/2nS9iiJ438sF7RNq9eZR0EVZszMadq1d83YPs4eYMV4c/u9iYQp26922I//Aw==
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // DemoLLDB
4 | //
5 | // Created by cjlin on 2019/9/19.
6 | // Copyright © 2019 cjlin. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | iPlayground2019
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
38 |
39 |
40 |
42 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // DemoLLDB
4 | //
5 | // Created by cjlin on 2019/9/19.
6 | // Copyright © 2019 cjlin. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: - Example 1
12 | public class ViewController: UIViewController {
13 |
14 | var isLoggedIn = false
15 |
16 | @IBAction func didTapButton(_ sender: Any) {
17 | if isLoggedIn {
18 | someAction()
19 | } else {
20 | requireLogin()
21 | }
22 | }
23 |
24 | func requireLogin() {
25 | print(#function)
26 | }
27 |
28 | func someAction() {
29 | print(#function)
30 | }
31 |
32 | public override func viewDidLoad() {
33 | super.viewDidLoad()
34 | }
35 |
36 | var fibonacci: [Int] = []
37 | @IBAction func didTapFibonacci(_ sender: Any) {
38 | fibonacci = FibonacciManager.shared.fibonacci()
39 | print(fibonacci)
40 | }
41 |
42 | var sessions: [SessionInfo]?
43 | @IBAction func didTapDownload(_ sender: Any) {
44 | //TODO: fetch session titles with view model
45 | }
46 | }
47 |
48 | // MARK: - Example 2
49 |
50 | public class FibonacciManager {
51 | public static let shared = FibonacciManager()
52 | public func fibonacci() -> [Int] {
53 | return [0, 1, 1, 2, 3, 5, 7] // wrong
54 | }
55 | }
56 |
57 | /*
58 | // Add this into REPL
59 | extension FibonacciManager {
60 | func correctFibonacci() -> [Int] {
61 | return [0, 1, 1, 2, 3, 5, 8] // correct
62 | }
63 | }
64 | */
65 |
66 |
67 | // MARK: - Example 3
68 |
69 | struct SessionResponse: Codable {
70 | let sessions: [SessionInfo]
71 | }
72 |
73 | struct SessionInfo: Codable {
74 | let title: String
75 | let presenter: String
76 | }
77 |
78 | // Execute at LLDB
79 | // e $ViewModel().download { self.sessions = $0 }
80 | // v self.sessions
81 |
82 | // Add at LLDB
83 | /*
84 | import Foundation
85 | class $ViewModel {
86 | let url = URL(string: "https://raw.githubusercontent.com/iplayground/SessionData/master/sessions.json")!
87 | func download(completion: @escaping ([SessionInfo]) -> Void) {
88 | let rl = CFRunLoopGetCurrent() // async task in lldb, remove later
89 | URLSession.shared.dataTask(
90 | with: url,
91 | completionHandler: { data, response, error in
92 | let response = try! JSONDecoder().decode(SessionResponse.self, from: data!)
93 | completion(response.sessions)
94 | CFRunLoopStop(rl)
95 | }).resume()
96 | CFRunLoopRun()
97 | }
98 | }
99 | */
100 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB.xcodeproj/xcshareddata/xcschemes/DemoLLDB.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
29 |
37 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/theme.css:
--------------------------------------------------------------------------------
1 | /* fork from: https://github.com/sfc-arch/remark-theme/blob/gh-pages/blue_standard/remark_theme_blue_standard.css*/
2 | /*
3 | * Font settings
4 | */
5 | @import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
6 | body {
7 | font-family: 'Helvetica Neue Light', 'Helvetica Light', 'ヒラギノ角ゴ ProN', 'Hiragino Kaku Gothic ProN', 'メイリオ', 'Meiryo', sans-serif;
8 | }
9 |
10 | /*
11 | * Global settings
12 | */
13 | .remark-slide-content h1,
14 | .remark-slide-content h2,
15 | .remark-slide-content h3 {
16 | font-weight: normal;
17 | }
18 | .remark-slide-content h3,
19 | .remark-slide-content h4,
20 | .remark-slide-content h5,
21 | .remark-slide-content p {
22 | margin: 0.5em 0;
23 | }
24 | .remark-slide-content {
25 | font-size: 1.5em;
26 | padding: 0.5em 2em;
27 | }
28 | .remark-slide-content h1 {
29 | font-size: 2.5em;
30 | }
31 | .remark-slide-content h2 {
32 | font-size: 1.7em;
33 | }
34 | .remark-slide-content.inverted {
35 | color: #fff;
36 | }
37 |
38 | /*
39 | * Code settings
40 | */
41 | .remark-code,
42 | .remark-inline-code {
43 | font-family: 'Ubuntu Mono';
44 | }
45 |
46 | /*
47 | * Slide number settings
48 | */
49 | .remark-slide-number {
50 | font-size: 0.8em;
51 | bottom: 0.1em;
52 | right: 0.5em;
53 | }
54 |
55 | /*
56 | * Background image settings
57 | */
58 | .remark-slide-content {
59 | background-size: cover !important;
60 | background-position: center !important;
61 | }
62 |
63 | /*
64 | * Font size class
65 | */
66 | .remark-slide-content .font-small {
67 | font-size: 0.7em;
68 | }
69 | .remark-slide-content .font-middle {
70 | font-size: 1em;
71 | }
72 | .remark-slide-content .font-large {
73 | font-size: 1.3em;
74 | }
75 |
76 | /*
77 | * Margin class
78 | */
79 | .remark-slide-content .margin-top-small {
80 | margin-top: 1em;
81 | }
82 | .remark-slide-content .margin-top-middle {
83 | margin-top: 2em;
84 | }
85 | .remark-slide-content .margin-top-large {
86 | margin-top: 4em;
87 | }
88 | .remark-slide-content .margin-bottom-small {
89 | margin-bottom: 1em;
90 | }
91 | .remark-slide-content .margin-bottom-middle {
92 | margin-bottom: 2em;
93 | }
94 | .remark-slide-content .margin-bottom-large {
95 | margin-bottom: 4em;
96 | }
97 | .remark-slide-content .margin-right-small {
98 | margin-right: 1em;
99 | }
100 | .remark-slide-content .margin-right-middle {
101 | margin-right: 2em;
102 | }
103 | .remark-slide-content .margin-right-large {
104 | margin-right: 4em;
105 | }
106 | .remark-slide-content .margin-left-small {
107 | margin-left: 1em;
108 | }
109 | .remark-slide-content .margin-left-middle {
110 | margin-left: 2em;
111 | }
112 | .remark-slide-content .margin-left-large {
113 | margin-left: 4em;
114 | }
115 | .remark-slide-content .padding-top-small {
116 | padding-top: 1em;
117 | }
118 | .remark-slide-content .padding-top-middle {
119 | padding-top: 2em;
120 | }
121 | .remark-slide-content .padding-top-large {
122 | padding-top: 4em;
123 | }
124 | .remark-slide-content .padding-bottom-small {
125 | padding-bottom: 1em;
126 | }
127 | .remark-slide-content .padding-bottom-middle {
128 | padding-bottom: 2em;
129 | }
130 | .remark-slide-content .padding-bottom-large {
131 | padding-bottom: 4em;
132 | }
133 | .remark-slide-content .padding-right-small {
134 | padding-right: 1em;
135 | }
136 | .remark-slide-content .padding-right-middle {
137 | padding-right: 2em;
138 | }
139 | .remark-slide-content .padding-right-large {
140 | padding-right: 4em;
141 | }
142 | .remark-slide-content .padding-left-small {
143 | padding-left: 1em;
144 | }
145 | .remark-slide-content .padding-left-middle {
146 | padding-left: 2em;
147 | }
148 | .remark-slide-content .padding-left-large {
149 | padding-left: 4em;
150 | }
151 |
152 | /*
153 | * Title page style
154 | */
155 | .remark-slide-content.title {
156 | padding: 0 2em;
157 | }
158 | .remark-slide-content.title {
159 | text-align: center;
160 | }
161 | .remark-slide-content.title::before {
162 | content: '';
163 | position: absolute;
164 | top: auto;
165 | bottom: 0;
166 | left: 0;
167 | width: 100%;
168 | height: 35%;
169 | background-color: black;
170 | }
171 | .remark-slide-content.title h1 {
172 | height: 65%;
173 | padding-top: 23%;
174 | margin: 0 0 0.7em 0;
175 | }
176 | .remark-slide-content.title p {
177 | position: relative;
178 | z-index: 1;
179 | color: #fff;
180 | }
181 | .remark-slide-content.title a {
182 | color: #fff;
183 | }
184 | .remark-slide-content.title a:hover {
185 | color: #888;
186 | }
187 | .remark-slide-content.title .remark-slide-number {
188 | color: #fff;
189 | }
190 |
191 | /*
192 | * Default page style
193 | */
194 | .remark-slide-content:not(.title):not(.blank)::before {
195 | content: '';
196 | position: absolute;
197 | left: 0;
198 | top: 0;
199 | width: 100%;
200 | height: 4.5em;
201 | margin: 0;
202 | padding: 0;
203 | background-color: black;
204 | }
205 | .remark-slide-content:not(.title):not(.blank) h2 {
206 | color: #fff;
207 | position: relative;
208 | z-index: 1;
209 | margin: 0;
210 | padding: 0.25em 0 0.6em 0;
211 | }
212 |
213 | /*
214 | * Vertical centered text
215 | */
216 | .remark-slide-content .vertical-center {
217 | display: table;
218 | table-layout: fixed;
219 | height: 85%;
220 | width: 100%;
221 | }
222 | .remark-slide-content.blank .vertical-center {
223 | height: 100%;
224 | }
225 | .remark-slide-content .vertical-center>* {
226 | display: table-cell;
227 | height: auto;
228 | vertical-align: middle;
229 | }
230 | .remark-slide-content .vertical-center::before,
231 | .remark-slide-content .vertical-center::after {
232 | display: table-row;
233 | content: '';
234 | }
235 |
236 | /*
237 | * Emphasized text
238 | */
239 | .remark-slide-content h4 {
240 | padding: 0.5em 1em;
241 | color: #fff;
242 | font-size: 1.25em;
243 | font-weight: normal;
244 | background-color: #2ecc71;
245 | border-radius: 10px;
246 | }
247 | .remark-slide-content .inverted h4 {
248 | background-color: transparent;
249 | border: 3px #27ae60 solid;
250 | color: #27ae60;
251 | }
252 | .remark-slide-content .inverted h4 a {
253 | color: #27ae60;
254 | }
255 |
256 | /*
257 | * Bold text
258 | */
259 | .remark-slide-content .bold {
260 | font-weight: bold;
261 | }
262 |
263 | /*
264 | * Link text
265 | */
266 | .remark-slide-content a {
267 | color: #000;
268 | }
269 | .remark-slide-content a:hover {
270 | color: #888;
271 | }
272 |
273 | /*
274 | * Quotation
275 | */
276 | .remark-slide-content .quote {
277 | font-family: serif;
278 | font-style: italic;
279 | }
280 | .remark-slide-content .quote::before {
281 | content: open-quote;
282 | }
283 | .remark-slide-content .quote::after {
284 | content: close-quote;
285 | }
286 |
287 | /*
288 | * Footnote
289 | */
290 | .remark-slide-content .footnote {
291 | color: #888;
292 | font-size: 0.7em;
293 | }
294 |
295 | /*
296 | * Listing style
297 | */
298 | .remark-slide-content ul>li {
299 | list-style: disc;
300 | position: relative;
301 | margin: 0.4em 0;
302 | font-size: 1.3em;
303 | }
304 | .remark-slide-content ul>li>ul>li::before {
305 | content: "";
306 | display: none;
307 | }
308 | .remark-slide-content ul>li>ul>li {
309 | list-style-type: circle;
310 | font-size: 0.95em;
311 | }
312 | .remark-slide-content ul>li>ul>li>ul>li {
313 | list-style-type: circle;
314 | }
315 | .remark-slide-content ol>li {
316 | margin: 0.4em 0;
317 | }
318 |
319 | /*
320 | * Code block
321 | */
322 | .remark-code {
323 | padding: 1em !important;
324 | border-radius: 10px;
325 | word-wrap: break-word;
326 | background-color: #FFF8E3 !important;
327 | }
328 |
329 | /*
330 | * Table
331 | */
332 | .remark-slide-content table {
333 | width: 100%;
334 | margin: 1em 0;
335 | border-collapse: separate;
336 | border-spacing: 3px;
337 | }
338 | .remark-slide-content table th {
339 | padding: 0.7em;
340 | background-color: #7f8c8d;
341 | color: #fff;
342 | font-weight: normal;
343 | }
344 | .remark-slide-content table td {
345 | padding: 0.7em;
346 | background-color: #ced4d8;
347 | }
348 | .remark-slide-content .inverted table {
349 | border-spacing: 0px;
350 | }
351 | .remark-slide-content .inverted table th {
352 | background-color: transparent;
353 | border: 2px solid #ced4d8;
354 | color: #000;
355 | font-weight: bold;
356 | }
357 | .remark-slide-content .inverted table td {
358 | background-color: transparent;
359 | border: 2px solid #ced4d8;
360 | }
361 | .remark-slide-content table th:first-child {
362 | border-radius: 10px 0 0 0;
363 | }
364 | .remark-slide-content table th:last-child {
365 | border-radius: 0 10px 0 0;
366 | }
367 | .remark-slide-content table tr:last-child td:first-child {
368 | border-radius: 0 0 0 10px;
369 | }
370 | .remark-slide-content table tr:last-child td:last-child {
371 | border-radius: 0 0 10px 0;
372 | }
373 |
374 | /*
375 | * Image sizing
376 | */
377 | .remark-slide-content .small img {
378 | max-height: 10em;
379 | min-height: 10em;
380 | }
381 | .remark-slide-content .middle img {
382 | max-height: 15em;
383 | min-height: 15em;
384 | }
385 | .remark-slide-content .large img {
386 | max-height: 20em;
387 | min-height: 20em;
388 | }
389 |
390 | /*
391 | * Customize
392 | */
393 | .remark-slide-content .grey {
394 | color: grey;
395 | }
396 |
--------------------------------------------------------------------------------
/assets/code/DemoLLDB/DemoLLDB.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | DBA7378D23335FDE00795B84 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA7378C23335FDE00795B84 /* AppDelegate.swift */; };
11 | DBA7378F23335FDE00795B84 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA7378E23335FDE00795B84 /* ViewController.swift */; };
12 | DBA7379223335FDE00795B84 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DBA7379023335FDE00795B84 /* Main.storyboard */; };
13 | DBA7379423335FDF00795B84 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DBA7379323335FDF00795B84 /* Assets.xcassets */; };
14 | DBA7379723335FDF00795B84 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DBA7379523335FDF00795B84 /* LaunchScreen.storyboard */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | DBA7378923335FDE00795B84 /* DemoLLDB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoLLDB.app; sourceTree = BUILT_PRODUCTS_DIR; };
19 | DBA7378C23335FDE00795B84 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
20 | DBA7378E23335FDE00795B84 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
21 | DBA7379123335FDE00795B84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
22 | DBA7379323335FDF00795B84 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
23 | DBA7379623335FDF00795B84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
24 | DBA7379823335FDF00795B84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
25 | /* End PBXFileReference section */
26 |
27 | /* Begin PBXFrameworksBuildPhase section */
28 | DBA7378623335FDE00795B84 /* Frameworks */ = {
29 | isa = PBXFrameworksBuildPhase;
30 | buildActionMask = 2147483647;
31 | files = (
32 | );
33 | runOnlyForDeploymentPostprocessing = 0;
34 | };
35 | /* End PBXFrameworksBuildPhase section */
36 |
37 | /* Begin PBXGroup section */
38 | DBA7378023335FDE00795B84 = {
39 | isa = PBXGroup;
40 | children = (
41 | DBA7378B23335FDE00795B84 /* DemoLLDB */,
42 | DBA7378A23335FDE00795B84 /* Products */,
43 | );
44 | sourceTree = "";
45 | };
46 | DBA7378A23335FDE00795B84 /* Products */ = {
47 | isa = PBXGroup;
48 | children = (
49 | DBA7378923335FDE00795B84 /* DemoLLDB.app */,
50 | );
51 | name = Products;
52 | sourceTree = "";
53 | };
54 | DBA7378B23335FDE00795B84 /* DemoLLDB */ = {
55 | isa = PBXGroup;
56 | children = (
57 | DBA7378C23335FDE00795B84 /* AppDelegate.swift */,
58 | DBA7378E23335FDE00795B84 /* ViewController.swift */,
59 | DBA7379023335FDE00795B84 /* Main.storyboard */,
60 | DBA7379323335FDF00795B84 /* Assets.xcassets */,
61 | DBA7379523335FDF00795B84 /* LaunchScreen.storyboard */,
62 | DBA7379823335FDF00795B84 /* Info.plist */,
63 | );
64 | path = DemoLLDB;
65 | sourceTree = "";
66 | };
67 | /* End PBXGroup section */
68 |
69 | /* Begin PBXNativeTarget section */
70 | DBA7378823335FDE00795B84 /* DemoLLDB */ = {
71 | isa = PBXNativeTarget;
72 | buildConfigurationList = DBA7379B23335FDF00795B84 /* Build configuration list for PBXNativeTarget "DemoLLDB" */;
73 | buildPhases = (
74 | DBA7378523335FDE00795B84 /* Sources */,
75 | DBA7378623335FDE00795B84 /* Frameworks */,
76 | DBA7378723335FDE00795B84 /* Resources */,
77 | );
78 | buildRules = (
79 | );
80 | dependencies = (
81 | );
82 | name = DemoLLDB;
83 | productName = DemoLLDB;
84 | productReference = DBA7378923335FDE00795B84 /* DemoLLDB.app */;
85 | productType = "com.apple.product-type.application";
86 | };
87 | /* End PBXNativeTarget section */
88 |
89 | /* Begin PBXProject section */
90 | DBA7378123335FDE00795B84 /* Project object */ = {
91 | isa = PBXProject;
92 | attributes = {
93 | LastSwiftUpdateCheck = 1030;
94 | LastUpgradeCheck = 1030;
95 | ORGANIZATIONNAME = cjlin;
96 | TargetAttributes = {
97 | DBA7378823335FDE00795B84 = {
98 | CreatedOnToolsVersion = 10.3;
99 | };
100 | };
101 | };
102 | buildConfigurationList = DBA7378423335FDE00795B84 /* Build configuration list for PBXProject "DemoLLDB" */;
103 | compatibilityVersion = "Xcode 9.3";
104 | developmentRegion = en;
105 | hasScannedForEncodings = 0;
106 | knownRegions = (
107 | en,
108 | Base,
109 | );
110 | mainGroup = DBA7378023335FDE00795B84;
111 | productRefGroup = DBA7378A23335FDE00795B84 /* Products */;
112 | projectDirPath = "";
113 | projectRoot = "";
114 | targets = (
115 | DBA7378823335FDE00795B84 /* DemoLLDB */,
116 | );
117 | };
118 | /* End PBXProject section */
119 |
120 | /* Begin PBXResourcesBuildPhase section */
121 | DBA7378723335FDE00795B84 /* Resources */ = {
122 | isa = PBXResourcesBuildPhase;
123 | buildActionMask = 2147483647;
124 | files = (
125 | DBA7379723335FDF00795B84 /* LaunchScreen.storyboard in Resources */,
126 | DBA7379423335FDF00795B84 /* Assets.xcassets in Resources */,
127 | DBA7379223335FDE00795B84 /* Main.storyboard in Resources */,
128 | );
129 | runOnlyForDeploymentPostprocessing = 0;
130 | };
131 | /* End PBXResourcesBuildPhase section */
132 |
133 | /* Begin PBXSourcesBuildPhase section */
134 | DBA7378523335FDE00795B84 /* Sources */ = {
135 | isa = PBXSourcesBuildPhase;
136 | buildActionMask = 2147483647;
137 | files = (
138 | DBA7378F23335FDE00795B84 /* ViewController.swift in Sources */,
139 | DBA7378D23335FDE00795B84 /* AppDelegate.swift in Sources */,
140 | );
141 | runOnlyForDeploymentPostprocessing = 0;
142 | };
143 | /* End PBXSourcesBuildPhase section */
144 |
145 | /* Begin PBXVariantGroup section */
146 | DBA7379023335FDE00795B84 /* Main.storyboard */ = {
147 | isa = PBXVariantGroup;
148 | children = (
149 | DBA7379123335FDE00795B84 /* Base */,
150 | );
151 | name = Main.storyboard;
152 | sourceTree = "";
153 | };
154 | DBA7379523335FDF00795B84 /* LaunchScreen.storyboard */ = {
155 | isa = PBXVariantGroup;
156 | children = (
157 | DBA7379623335FDF00795B84 /* Base */,
158 | );
159 | name = LaunchScreen.storyboard;
160 | sourceTree = "";
161 | };
162 | /* End PBXVariantGroup section */
163 |
164 | /* Begin XCBuildConfiguration section */
165 | DBA7379923335FDF00795B84 /* Debug */ = {
166 | isa = XCBuildConfiguration;
167 | buildSettings = {
168 | ALWAYS_SEARCH_USER_PATHS = NO;
169 | CLANG_ANALYZER_NONNULL = YES;
170 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
171 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
172 | CLANG_CXX_LIBRARY = "libc++";
173 | CLANG_ENABLE_MODULES = YES;
174 | CLANG_ENABLE_OBJC_ARC = YES;
175 | CLANG_ENABLE_OBJC_WEAK = YES;
176 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
177 | CLANG_WARN_BOOL_CONVERSION = YES;
178 | CLANG_WARN_COMMA = YES;
179 | CLANG_WARN_CONSTANT_CONVERSION = YES;
180 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
181 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
182 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
183 | CLANG_WARN_EMPTY_BODY = YES;
184 | CLANG_WARN_ENUM_CONVERSION = YES;
185 | CLANG_WARN_INFINITE_RECURSION = YES;
186 | CLANG_WARN_INT_CONVERSION = YES;
187 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
188 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
189 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
190 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
191 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
192 | CLANG_WARN_STRICT_PROTOTYPES = YES;
193 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
194 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
195 | CLANG_WARN_UNREACHABLE_CODE = YES;
196 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
197 | CODE_SIGN_IDENTITY = "iPhone Developer";
198 | COPY_PHASE_STRIP = NO;
199 | DEBUG_INFORMATION_FORMAT = dwarf;
200 | ENABLE_STRICT_OBJC_MSGSEND = YES;
201 | ENABLE_TESTABILITY = YES;
202 | GCC_C_LANGUAGE_STANDARD = gnu11;
203 | GCC_DYNAMIC_NO_PIC = NO;
204 | GCC_NO_COMMON_BLOCKS = YES;
205 | GCC_OPTIMIZATION_LEVEL = 0;
206 | GCC_PREPROCESSOR_DEFINITIONS = (
207 | "DEBUG=1",
208 | "$(inherited)",
209 | );
210 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
211 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
212 | GCC_WARN_UNDECLARED_SELECTOR = YES;
213 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
214 | GCC_WARN_UNUSED_FUNCTION = YES;
215 | GCC_WARN_UNUSED_VARIABLE = YES;
216 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
217 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
218 | MTL_FAST_MATH = YES;
219 | ONLY_ACTIVE_ARCH = YES;
220 | SDKROOT = iphoneos;
221 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
222 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
223 | };
224 | name = Debug;
225 | };
226 | DBA7379A23335FDF00795B84 /* Release */ = {
227 | isa = XCBuildConfiguration;
228 | buildSettings = {
229 | ALWAYS_SEARCH_USER_PATHS = NO;
230 | CLANG_ANALYZER_NONNULL = YES;
231 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
232 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
233 | CLANG_CXX_LIBRARY = "libc++";
234 | CLANG_ENABLE_MODULES = YES;
235 | CLANG_ENABLE_OBJC_ARC = YES;
236 | CLANG_ENABLE_OBJC_WEAK = YES;
237 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
238 | CLANG_WARN_BOOL_CONVERSION = YES;
239 | CLANG_WARN_COMMA = YES;
240 | CLANG_WARN_CONSTANT_CONVERSION = YES;
241 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
242 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
243 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
244 | CLANG_WARN_EMPTY_BODY = YES;
245 | CLANG_WARN_ENUM_CONVERSION = YES;
246 | CLANG_WARN_INFINITE_RECURSION = YES;
247 | CLANG_WARN_INT_CONVERSION = YES;
248 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
249 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
250 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
251 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
252 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
253 | CLANG_WARN_STRICT_PROTOTYPES = YES;
254 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
255 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
256 | CLANG_WARN_UNREACHABLE_CODE = YES;
257 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
258 | CODE_SIGN_IDENTITY = "iPhone Developer";
259 | COPY_PHASE_STRIP = NO;
260 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
261 | ENABLE_NS_ASSERTIONS = NO;
262 | ENABLE_STRICT_OBJC_MSGSEND = YES;
263 | GCC_C_LANGUAGE_STANDARD = gnu11;
264 | GCC_NO_COMMON_BLOCKS = YES;
265 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
266 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
267 | GCC_WARN_UNDECLARED_SELECTOR = YES;
268 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
269 | GCC_WARN_UNUSED_FUNCTION = YES;
270 | GCC_WARN_UNUSED_VARIABLE = YES;
271 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
272 | MTL_ENABLE_DEBUG_INFO = NO;
273 | MTL_FAST_MATH = YES;
274 | SDKROOT = iphoneos;
275 | SWIFT_COMPILATION_MODE = wholemodule;
276 | SWIFT_OPTIMIZATION_LEVEL = "-O";
277 | VALIDATE_PRODUCT = YES;
278 | };
279 | name = Release;
280 | };
281 | DBA7379C23335FDF00795B84 /* Debug */ = {
282 | isa = XCBuildConfiguration;
283 | buildSettings = {
284 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
285 | CODE_SIGN_STYLE = Automatic;
286 | INFOPLIST_FILE = DemoLLDB/Info.plist;
287 | LD_RUNPATH_SEARCH_PATHS = (
288 | "$(inherited)",
289 | "@executable_path/Frameworks",
290 | );
291 | PRODUCT_BUNDLE_IDENTIFIER = cj.DemoLLDB;
292 | PRODUCT_NAME = "$(TARGET_NAME)";
293 | SWIFT_VERSION = 5.0;
294 | TARGETED_DEVICE_FAMILY = "1,2";
295 | };
296 | name = Debug;
297 | };
298 | DBA7379D23335FDF00795B84 /* Release */ = {
299 | isa = XCBuildConfiguration;
300 | buildSettings = {
301 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
302 | CODE_SIGN_STYLE = Automatic;
303 | INFOPLIST_FILE = DemoLLDB/Info.plist;
304 | LD_RUNPATH_SEARCH_PATHS = (
305 | "$(inherited)",
306 | "@executable_path/Frameworks",
307 | );
308 | PRODUCT_BUNDLE_IDENTIFIER = cj.DemoLLDB;
309 | PRODUCT_NAME = "$(TARGET_NAME)";
310 | SWIFT_VERSION = 5.0;
311 | TARGETED_DEVICE_FAMILY = "1,2";
312 | };
313 | name = Release;
314 | };
315 | /* End XCBuildConfiguration section */
316 |
317 | /* Begin XCConfigurationList section */
318 | DBA7378423335FDE00795B84 /* Build configuration list for PBXProject "DemoLLDB" */ = {
319 | isa = XCConfigurationList;
320 | buildConfigurations = (
321 | DBA7379923335FDF00795B84 /* Debug */,
322 | DBA7379A23335FDF00795B84 /* Release */,
323 | );
324 | defaultConfigurationIsVisible = 0;
325 | defaultConfigurationName = Release;
326 | };
327 | DBA7379B23335FDF00795B84 /* Build configuration list for PBXNativeTarget "DemoLLDB" */ = {
328 | isa = XCConfigurationList;
329 | buildConfigurations = (
330 | DBA7379C23335FDF00795B84 /* Debug */,
331 | DBA7379D23335FDF00795B84 /* Release */,
332 | );
333 | defaultConfigurationIsVisible = 0;
334 | defaultConfigurationName = Release;
335 | };
336 | /* End XCConfigurationList section */
337 | };
338 | rootObject = DBA7378123335FDE00795B84 /* Project object */;
339 | }
340 |
--------------------------------------------------------------------------------
/slides.md:
--------------------------------------------------------------------------------
1 | class: title
2 |
3 | # 10x Faster App Dev/Verification Cycle
4 |
5 | The Survival Guide of Building Huge App
6 |
7 | CJ Lin
8 |
9 | ???
10 |
11 | This talk is not about lower overall build time
12 |
13 | It's about tips of faster dev/verification cycle
14 |
15 | Let's start it!
16 |
17 | ---
18 |
19 | ## About
20 |
21 | .left-column-80[
22 | ```swift
23 | struct Profile {
24 |
25 | let name = "CJ Lin"
26 |
27 | var identity = "iOS Nerd"
28 |
29 | var company = "LINE"
30 |
31 | var blog = "https://ejameslin.github.io"
32 |
33 | var github = "https://github.com/eJamesLin"
34 |
35 | var line = "ejameslin"
36 |
37 | var twitter = "@eJamesLin"
38 | }
39 | ```
40 | ]
41 |
42 | .right-column-20[
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | ]
51 |
52 | ---
53 |
54 | class: blank
55 |
56 | .vertical-center.center[
57 | ## Don't Build-and-Run Whole App
58 | ]
59 |
60 | ---
61 |
62 | ## Outline
63 |
64 | ### LLDB Code Injection
65 |
66 | ???
67 |
68 | Minimize the number of rebuild
69 |
70 | --
71 |
72 | ### Develop only at Framework
73 | --
74 |
75 | ### Verify the Framework
76 |
77 | ---
78 |
79 | ## Outline
80 |
81 | ### LLDB Code Injection
82 |
83 | .grey[
84 | ### Develop only at Framework
85 |
86 | ### Verify the Framework
87 | ]
88 |
89 | ---
90 |
91 | ## LLDB Code Injection
92 |
93 | * LLDB and Breakpoints
94 |
95 | * Modify control flow without rebuild
96 |
97 | ---
98 |
99 | ## Code Injection Example - Login
100 |
101 | .vertical-center.center[
102 |
103 | ]
104 |
105 | ---
106 |
107 | ## Code Injection Example - Login
108 |
109 | .vertical-center.center[
110 |
111 | ]
112 |
113 | ---
114 |
115 | ## Code Injection - REPL
116 |
117 | * LLDB + REPL
118 |
119 | * Read-Eval-Print-Loop (REPL)
120 |
121 | * Access public functions and global variables
122 |
123 | * Inject new functions
124 |
125 | ---
126 |
127 | ## Code Injection Example - Fibonacci
128 |
129 | .vertical-center.center[
130 |
131 | ]
132 |
133 | ---
134 |
135 | ## Code Injection Example - Fibonacci
136 |
137 | * Type `repl` to enter
138 |
139 | .center[
140 |
141 | ]
142 |
143 | ---
144 |
145 | ## Code Injection Example - Fibonacci
146 |
147 | * Inject new function
148 |
149 | .center[
150 |
151 | ]
152 |
153 | ---
154 |
155 | ## Code Injection Example - Fibonacci
156 |
157 | * Call the function and verify
158 |
159 | .center[
160 |
161 | ]
162 |
163 | ---
164 |
165 | ## Code Injection Example - Fibonacci
166 |
167 | * Prefix `:` to run LLDB command
168 |
169 | .center[
170 |
171 | ]
172 |
173 | ---
174 |
175 | ## Code Injection Example - Fibonacci
176 |
177 | * Type single colon to return back to LLDB
178 |
179 | .center[
180 |
181 | ]
182 |
183 | ---
184 |
185 | ## Code Injection Example - Fibonacci
186 |
187 | * Modify variable by calling the injected function
188 |
189 | .center[
190 |
191 | ]
192 |
193 | ---
194 |
195 | ## Code Injection Example - API
196 |
197 | * In the code todo
198 | * Implement a view model to download API json
199 |
200 | .center[
201 |
202 | ]
203 |
204 | ---
205 |
206 | ## Code Injection Example - API
207 |
208 | * Type `e` in LLDB to enter multi-line expressions
209 |
210 | .center[
211 |
212 | ]
213 |
214 | ---
215 |
216 | ## Code Injection Example - API
217 |
218 | * Inject ViewModel and API code
219 |
220 | .center[
221 |
222 | ]
223 |
224 | ---
225 |
226 | ## Code Injection Example - API
227 |
228 | * Json URL
229 |
230 | .center[
231 |
232 | ]
233 |
234 | ---
235 |
236 | ## Code Injection Example - API
237 |
238 | * Download
239 |
240 | .center[
241 |
242 | ]
243 |
244 | ---
245 |
246 | ## Code Injection Example - API
247 |
248 | * Runloop handling at LLDB
249 |
250 | .center[
251 |
252 | ]
253 |
254 | ---
255 |
256 | ## Code Injection Example - API
257 |
258 | * Call the injected function
259 |
260 | .center[
261 |
262 | ]
263 |
264 | ---
265 |
266 | ## Code Injection Example - API
267 |
268 | * Inspect the result
269 |
270 | .center[
271 |
272 | ]
273 |
274 | ---
275 |
276 | ## Outline
277 |
278 | .grey[
279 | ### LLDB Code Injection
280 | ]
281 |
282 | ### Develop only at Framework
283 |
284 | .grey[
285 | ### Verify the Framework
286 | ]
287 |
288 | ---
289 |
290 | ## Let's do a little survey...
291 |
292 | ???
293 |
294 | App build time > 10 mins
295 | --
296 |
297 | ### Can't tolerate LONG BUILD TIME?
298 |
299 | ### Let's solve it !!!
300 |
301 | .center[
302 |
303 | ]
304 |
305 | ---
306 |
307 | ## Build Time
308 |
309 | ### Main Target
310 |
311 | .center[
312 |
313 | ]
314 |
315 | ???
316 |
317 | MacBook Pro (15-inch, 2017)
318 |
319 | 3.1 GHz Intel Core i7
320 |
321 | 16 GB 2133 MHz LPDDR3
322 |
323 | --
324 |
325 | ### Partitioned Framework Target
326 |
327 | .center[
328 |
329 | ]
330 |
331 | ???
332 |
333 | Build time quickly disappear for indexing after build at Xcode title bar...
334 |
335 | ---
336 |
337 | class: blank
338 |
339 | .vertical-center.center[
340 | ## Don't Build-and-Run Whole App
341 | ]
342 |
343 | ---
344 |
345 | ## Framework Partitioning Tips
346 |
347 | .center[
348 |
349 | ]
350 |
351 | ???
352 |
353 | Feature could be MVC or MVVM or MVP
354 |
355 | ---
356 |
357 | ## Framework Partitioning Tips
358 |
359 | .center[
360 |
361 | ]
362 |
363 | ---
364 |
365 | ## Framework Partitioning Tips
366 |
367 | .center[
368 |
369 | ]
370 |
371 | ---
372 |
373 | ## Let's start from small step
374 |
375 | .vertical-center.center[
376 | ### Ideal partition is too ideal
377 | ]
378 |
379 | ---
380 |
381 | ## Let's start from small step
382 |
383 | .vertical-center.center[
384 | ### Small Testing-Only Framework
385 | ]
386 |
387 | ---
388 |
389 | ## Small Testing-Only Framework
390 |
391 | * Build Fast
392 | * Feature related code only
393 | * Few compile source count
394 |
395 | --
396 |
397 | .right-column-20[
398 |
399 | ]
400 |
401 | * Testing-Only
402 | * Code in both targets
403 | * Not embedded in others
404 | * Not linked by others
405 | --
406 |
407 | * Easy to apply on existing project
408 |
409 | ---
410 |
411 | ## Framework Partitioning Tips
412 |
413 | * Coordinator / Router
414 |
415 | ---
416 |
417 | ## Coordinator / Router
418 |
419 | ### How `Coordinator` eliminate dependency?
420 |
421 | * Example
422 | * In `Profile`, Click `Edit` button, Show `EditProfile`
423 |
424 | .center[
425 |
426 | ]
427 |
428 | --
429 |
430 | * `Profile` is depends on `EditProfile`
431 | --
432 |
433 | * Difficult to move into framework
434 |
435 | ---
436 |
437 | ## Coordinator / Router
438 |
439 | .vertical-center.center[
440 |
441 | ]
442 |
443 | ---
444 |
445 | ## Coordinator / Router
446 |
447 | .vertical-center.center[
448 |
449 | ]
450 |
451 | ---
452 |
453 | ## Coordinator / Router
454 |
455 | .vertical-center.center[
456 |
457 | ]
458 |
459 | ---
460 |
461 | ## Coordinator / Router
462 |
463 | ```swift
464 | protocol ProfileViewControllerDelegate: class {
465 | viewControllerDidSelectEdit(_ vc: ProfileViewController) {}
466 | }
467 |
468 | class ProfileViewController: UIViewController {
469 | weak var delegate: ProfileViewControllerDelegate?
470 | }
471 | ```
472 |
473 | --
474 |
475 | ```swift
476 | class Coordinator: ProfileViewControllerDelegate {
477 | viewControllerDidSelectEdit(_ vc: ProfileViewController) {
478 | // show EditProfileViewController...
479 | }
480 | }
481 | ```
482 |
483 | ---
484 |
485 | ## Framework Partitioning Tips
486 |
487 | * .grey[Coordinator / Router]
488 |
489 | * Dependency Injection
490 |
491 | ---
492 |
493 | ## Dependency Injection Example
494 |
495 | .center[
496 |
497 | ]
498 | --
499 |
500 | .center[
501 |
502 | ]
503 | --
504 |
505 | .center[
506 |
507 | ]
508 |
509 | ---
510 |
511 | ## Dependency Injection Example
512 | --
513 |
514 | ```
515 | protocol AnalyticsProtocol {
516 | func track(screen: AnalyticsScreen)
517 | }
518 | ```
519 |
520 | ???
521 |
522 | Start from `AnalyticsProtocol` definition
523 | --
524 |
525 | ```
526 | class Analytics: AnalyticsProtocol {
527 | func track(screen: AnalyticsScreen) {
528 | GA.track(screen: screen)
529 | }
530 | }
531 | ```
532 |
533 | ???
534 |
535 | `Analytics` conforms to the protocol
536 | --
537 |
538 | ```
539 | class FeedController: UIViewController {
540 | let analytics: AnalyticsProtocol
541 | init(analytics: AnalyticsProtocol) {
542 | self.analytics = analytics
543 | super.init(nibName: nil, bundle: nil)
544 | }
545 | override func viewDidLoad() {
546 | super.viewDidLoad()
547 | analytics.track(screen: .feed)
548 | }
549 | ```
550 |
551 | ???
552 |
553 | Controller is now depends on only the protocol,
554 | not the `Analytics`, nor the implementation detail GA.
555 |
556 | ---
557 |
558 | ## Framework Partitioning Tips
559 |
560 | * Ready for framework partitioning
561 |
562 | .center[
563 |
564 | ]
565 |
566 | ---
567 |
568 | ## Outline
569 |
570 | .grey[
571 | ### Code Injection to minimize rebuild
572 |
573 | ### Develop only at Framework
574 | ]
575 |
576 | ### Verify the Framework
577 |
578 | ---
579 |
580 | ## Framework + Live View
581 |
582 | ### SwiftUI Canvas Preview
583 |
584 | ### Playground
585 |
586 | ---
587 |
588 | ## Framework + Live View
589 |
590 | ### SwiftUI Canvas Preview
591 |
592 | .grey[
593 | ### Playground
594 | ]
595 |
596 | ---
597 |
598 | ## SwiftUI Canvas Preview Advantage
599 | --
600 |
601 | .left-column[
602 | .font-large[Live Preview]
603 | ]
604 |
605 | .right-column[
606 | * Interactable
607 | ]
608 | --
609 |
610 | .right-column[
611 | * Can also preview UIViewController / UIView
612 |
613 | * Even if the minimum target is iOS 12 and below
614 | ]
615 |
616 | ---
617 |
618 | ## SwiftUI Preview at iOS 12 and below
619 |
620 | Though SwiftUI cannot be used at iOS 12 and below
621 |
622 | Still could preview existing screens
623 |
624 | ```
625 | The `@available(iOS 13.0, *)` is not enough...
626 |
627 | dyld: Library not loaded: /System/Library/Frameworks/SwiftUI.framework/SwiftUI
628 | ```
629 |
630 | --
631 |
632 | ```
633 | Known Issues and Workaround: -weak_framework
634 | Apps containing SwiftUI inside a Swift package might not run on versions of iOS earlier than iOS 13. (53706729)
635 | ```
636 |
637 | .center[
638 |
639 |
640 | .footnote[[iOS 13 Release Notes](https://developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes)]
641 | ]
642 |
643 | ---
644 |
645 | ## SwiftUI Canvas Preview Advantage
646 |
647 | .left-column[
648 | .font-large.grey[Live Preview]
649 |
650 | .font-large[Fast Access]
651 | ]
652 |
653 | .right-column[
654 | * Render the page directly
655 |
656 | * No need following steps
657 | 1. Select A
658 | 2. Scroll
659 | 3. Click B
660 | 4. ...
661 | ]
662 |
663 | ---
664 |
665 | ## SwiftUI Canvas Preview Advantage
666 |
667 | .left-column[
668 | .font-large.grey[Live Preview]
669 |
670 | .font-large.grey[Fast Access]
671 |
672 | .font-large[Preview device size]
673 | ]
674 |
675 | .right-column[
676 | ```swift
677 | struct ContentView_Previews: PreviewProvider {
678 | static var previews: some View {
679 | ContentView()
680 | .previewDevice("iPhone 11")
681 | }
682 | }
683 | ```
684 | ]
685 |
686 | ---
687 |
688 | ## SwiftUI Canvas Preview Advantage
689 |
690 | .left-column[
691 | .font-large.grey[Live Preview]
692 |
693 | .font-large.grey[Fast Access]
694 |
695 | .font-large.grey[Preview device size]
696 |
697 | .font-large[Group Preview]
698 | ]
699 |
700 | .right-column[
701 | ```
702 | struct ContentView_Previews: PreviewProvider {
703 | static var previews: some View {
704 | Group {
705 | ContentView()
706 | .previewDevice("iPhone SE")
707 |
708 | ContentView()
709 | .previewDevice("iPhone 11")
710 | }
711 | }
712 | }
713 | ```
714 | ]
715 |
716 | ---
717 |
718 | ## SwiftUI Canvas Preview Advantage
719 |
720 | .left-column[
721 | .font-large.grey[Live Preview]
722 |
723 | .font-large.grey[Fast Access]
724 |
725 | .font-large.grey[Preview device size]
726 |
727 | .font-large.grey[Group Preview]
728 |
729 | .font-large[Vary Language]
730 | ]
731 |
732 | .right-column[
733 | ```
734 | struct SwiftUIText: View {
735 | var body: some View {
736 | Text("HelloKey")
737 | }
738 | }
739 | struct PreviewSwiftUIText: PreviewProvider {
740 | static var previews: some View {
741 | Group {
742 | SwiftUIText()
743 | .environment(\.locale,
744 | Locale(identifier: "en"))
745 | .previewDisplayName("en")
746 |
747 | SwiftUIText()
748 | .environment(\.locale,
749 | Locale(identifier: "ja"))
750 | .previewDisplayName("ja")
751 | }
752 | .previewLayout(.sizeThatFits)
753 | }
754 | }
755 | ```
756 | ]
757 |
758 | .left-column[
759 |
760 | ]
761 |
762 | ---
763 |
764 | ## SwiftUI Canvas Preview Advantage
765 |
766 | .left-column[
767 | .font-large.grey[Live Preview]
768 |
769 | .font-large.grey[Fast Access]
770 |
771 | .font-large.grey[Preview device size]
772 |
773 | .font-large.grey[Group Preview]
774 |
775 | .font-large[Vary Language]
776 | ]
777 |
778 | .right-column[
779 | ### Not work at `NSLocalizedString`
780 | ]
781 |
782 | ---
783 |
784 | ## SwiftUI Preview + NSLocalizedString
785 |
786 | .center[
787 |
788 | ]
789 |
790 | ---
791 |
792 | ## SwiftUI Canvas Preview + Framework
793 |
794 | ### Known Issue
795 |
796 | ```
797 | Previews in packages always perform a full build of the active scheme. (51030302)
798 | ```
799 | .footnote[[Xcode 11 Release Notes](https://developer.apple.com/documentation/xcode_release_notes/xcode_11_release_notes)]
800 |
801 | .center[
802 |
803 | ]
804 |
805 | ---
806 |
807 | ## SwiftUI Canvas Preview + Framework
808 |
809 | ```
810 | Previews in packages always perform a full build of the active scheme. (51030302)
811 | ```
812 |
813 | Main Scheme
814 |
815 | .center[
816 |
817 | ]
818 |
819 | --
820 |
821 | Framework Scheme - Solution
822 |
823 | .center[
824 |
825 | ]
826 |
827 | ---
828 |
829 | ## Framework + Live View
830 |
831 | .grey[
832 | ### SwiftUI Canvas Preview
833 | ]
834 |
835 | ### Playground
836 |
837 | ---
838 |
839 | ## Playground + Framework
840 |
841 | Currently Playground is more stable than SwiftUI canvas preview...
842 |
843 | .center[
844 |
845 | ]
846 |
847 | ---
848 |
849 | ## Playground Advantage
850 |
851 | .left-column[
852 | .font-large[Live View]
853 | ]
854 |
855 | .right-column[
856 | * Interactable
857 | ]
858 |
859 | ---
860 |
861 | ## Playground Advantage
862 |
863 | .left-column[
864 | .font-large.grey[Live View]
865 |
866 | .font-large[Fast Access]
867 | ]
868 |
869 | .right-column[
870 | * Render the page directly
871 |
872 | * No need following steps
873 | 1. Select A
874 | 2. Scroll
875 | 3. Click B
876 | 4. ...
877 | ]
878 |
879 | ---
880 |
881 | ## Playground Advantage
882 |
883 | .left-column[
884 | .font-large.grey[Live View]
885 |
886 | .font-large.grey[Fast Access]
887 |
888 | .font-large[Inline Display]
889 | ]
890 |
891 | .right-column[
892 |
893 | ]
894 |
895 | ---
896 |
897 | ## Playground Advantage
898 |
899 | .left-column[
900 | .font-large.grey[Live View]
901 |
902 | .font-large.grey[Fast Access]
903 |
904 | .font-large.grey[Inline Display]
905 |
906 | .font-large[Run Step by Step]
907 | ]
908 |
909 | .right-column[
910 | * View change on the fly
911 |
912 |
913 | ]
914 | --
915 |
916 | .right-column[
917 |
918 | ]
919 |
920 | ???
921 |
922 | Similar to Scripting Language
923 |
924 | ---
925 |
926 | ## Playground Advantage
927 |
928 | .left-column[
929 | .font-large.grey[Live View]
930 |
931 | .font-large.grey[Fast Access]
932 |
933 | .font-large.grey[Inline Display]
934 |
935 | .font-large[Run Step by Step]
936 | ]
937 |
938 | .right-column[
939 | * View change on the fly
940 | ]
941 | .right-column[
942 | * Perfect for network response decoding trial
943 | ]
944 |
945 | ---
946 |
947 | ## Playground Advantage
948 |
949 | .left-column[
950 | .font-large.grey[Live View]
951 |
952 | .font-large.grey[Fast Access]
953 |
954 | .font-large.grey[Inline Display]
955 |
956 | .font-large.grey[Run Step by Step]
957 |
958 | .font-large[Vary Screen Size]
959 | ]
960 |
961 | .right-column[
962 | ```swift
963 | viewController.preferredContentSize = Some Size
964 | ```
965 | ]
966 |
967 | ???
968 |
969 | No safe area...
970 |
971 | ---
972 |
973 | ## Playground Advantage
974 |
975 | .left-column[
976 | .font-large.grey[Live View]
977 |
978 | .font-large.grey[Fast Access]
979 |
980 | .font-large.grey[Inline Display]
981 |
982 | .font-large.grey[Run Step by Step]
983 |
984 | .font-large.grey[Vary Screen Size]
985 |
986 | .font-large[Vary Language]
987 | ]
988 |
989 | .right-column[
990 | * Use `NSLocalizedString` with specified language sub-bundle
991 |
992 |
993 | ]
994 |
995 | ---
996 |
997 | ## Test Driven Development in Playground
998 |
999 | * To build faster at every iteration
1000 | * SUT (System Under Test) in Framework
1001 | * Start unit test in playground, move to test target for CI after completed
1002 |
1003 | ```
1004 | MyUnitTests.defaultTestSuite().run() // in playground
1005 | ```
1006 |
1007 | .center[
1008 |
1009 | .font-small[[Image Source](https://www.allaboutcircuits.com/technical-articles/how-test-driven-development-can-help-you-write-better-unit-tests/)]
1010 | ]
1011 |
1012 | ---
1013 |
1014 | ## Playground Driven Development
1015 |
1016 | * From Kickstarter [Open Source](https://github.com/kickstarter/ios-oss) and [Speech](https://www.youtube.com/watch?v=DrdxSNG-_DE)
1017 | * All code in Framework
1018 | * Every page inspectable in playground
1019 |
1020 | .center[
1021 |
1022 | ]
1023 |
1024 | ---
1025 |
1026 | class: blank
1027 |
1028 | .vertical-center.center[
1029 | ## Don't Build-and-Run Whole App
1030 | ]
1031 |
1032 | ---
1033 |
1034 | ## Thank You
1035 |
1036 | * The slides is made by Markdown powered by [remark](https://github.com/gnab/remark)
1037 |
1038 | * The markdown and sample code of the slides could be found [here](https://github.com/eJamesLin/FastAppDevCycle)
1039 |
1040 | .center[
]
1041 |
1042 | * Happy Coding and Thank You
1043 |
1044 |
--------------------------------------------------------------------------------
/assets/profile/SlidesQRCode.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------