├── 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 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | --------------------------------------------------------------------------------