├── .eslintignore ├── .prettierignore ├── README ├── Cover.jpg ├── Cover.psd ├── Syntax.png ├── Syntax.psd └── Syntax@1x.png ├── assets ├── ScriptGen.png └── SwiftCode.png ├── Example ├── iOS │ ├── Example │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── ViewController.swift │ │ ├── Info.plist │ │ ├── SceneDelegate.swift │ │ └── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ └── Example.xcodeproj │ │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcuserdata │ │ │ └── justinbush.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcuserdata │ │ └── justinbush.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Example (iOS).xcscheme │ │ └── project.pbxproj ├── macOS │ ├── Example │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Example.entitlements │ │ ├── WindowController.swift │ │ ├── AppDelegate.swift │ │ ├── Info.plist │ │ ├── ViewController.swift │ │ └── Base.lproj │ │ │ └── Main.storyboard │ └── Example.xcodeproj │ │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcuserdata │ │ │ └── justinbush.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcuserdata │ │ └── justinbush.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Example (macOS).xcscheme │ │ └── project.pbxproj ├── WebContent │ ├── apple-system.css │ ├── index.html │ └── style.css ├── Shared │ ├── Script.swift │ ├── WebKit │ │ ├── JSManager.swift │ │ └── WKRunScript.swift │ └── Includes │ │ └── Extensions.swift └── README.md ├── .prettierrc ├── .eslintrc.json ├── src ├── types │ └── global.d.ts └── index.ts ├── .gitignore ├── tsconfig.json ├── package.json ├── LICENSE └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /README/Cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/README/Cover.jpg -------------------------------------------------------------------------------- /README/Cover.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/README/Cover.psd -------------------------------------------------------------------------------- /README/Syntax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/README/Syntax.png -------------------------------------------------------------------------------- /README/Syntax.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/README/Syntax.psd -------------------------------------------------------------------------------- /README/Syntax@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/README/Syntax@1x.png -------------------------------------------------------------------------------- /assets/ScriptGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/assets/ScriptGen.png -------------------------------------------------------------------------------- /assets/SwiftCode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/assets/SwiftCode.png -------------------------------------------------------------------------------- /Example/iOS/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/macOS/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": false, 6 | "bracketSpacing": true, 7 | "arrowParens": "always", 8 | "printWidth": 100 9 | } 10 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/macOS/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/iOS/Example/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Example/macOS/Example/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Example/WebContent/apple-system.css: -------------------------------------------------------------------------------- 1 | /* Apple System Fonts (CSS) 2 | * https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/typography/ 3 | */ 4 | 5 | title { 6 | size: 26pt; 7 | font-weight: 400; 8 | line-height: 32pt; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/project.xcworkspace/xcuserdata/justinbush.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/Example/iOS/Example.xcodeproj/project.xcworkspace/xcuserdata/justinbush.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Example/macOS/Example.xcodeproj/project.xcworkspace/xcuserdata/justinbush.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inter-ops/WKTypeScript/HEAD/Example/macOS/Example.xcodeproj/project.xcworkspace/xcuserdata/justinbush.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "plugins": ["@typescript-eslint"], 4 | "extends": [ 5 | "eslint:recommended", 6 | "plugin:@typescript-eslint/recommended" 7 | ], 8 | "env": { 9 | "browser": true, 10 | "node": true 11 | }, 12 | "rules": {} 13 | } 14 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/macOS/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/types/global.d.ts: -------------------------------------------------------------------------------- 1 | // global types 2 | type WKScriptMessage = 3 | | number 4 | | string 5 | | Date 6 | | Record 7 | | Array 8 | | null; 9 | 10 | interface Window { 11 | webkit: { 12 | messageHandlers: { 13 | [handlerName: string]: { 14 | postMessage: (message: WKScriptMessage) => void; 15 | }; 16 | }; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /Example/WebContent/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Title

9 |

Subtitle

10 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

11 | 12 | 13 | -------------------------------------------------------------------------------- /Example/macOS/Example/Example.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Example/macOS/Example/WindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-21. 6 | // 7 | 8 | import Cocoa 9 | 10 | class WindowController: NSWindowController, NSToolbarDelegate { 11 | 12 | override func windowDidLoad() { 13 | super.windowDidLoad() 14 | 15 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 16 | } 17 | 18 | @IBAction func toggleMode(_ sender: NSToolbarItem) { 19 | NotificationCenter.default.post(Notification(name: .didToggleMode)) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/xcuserdata/justinbush.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Example (iOS).xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C207E76525924E5800A04149 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/macOS/Example.xcodeproj/xcuserdata/justinbush.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Example (macOS).xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C2C0A685258E7A680038A67C 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | *.sql 27 | *.sqlite 28 | 29 | # OS generated files # 30 | ###################### 31 | .DS_Store 32 | .DS_Store? 33 | ._* 34 | .Spotlight-V100 35 | .Trashes 36 | ehthumbs.db 37 | Thumbs.db 38 | 39 | 40 | # Node.js / Typescript 41 | node_modules 42 | dist 43 | .eslintcache -------------------------------------------------------------------------------- /Example/Shared/Script.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Script.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-22. 6 | // 7 | 8 | import Foundation 9 | 10 | enum Script { 11 | 12 | case toggleMode 13 | 14 | var name: String { 15 | switch self { 16 | case .toggleMode: return "toggleMode();" 17 | } 18 | } 19 | 20 | var code: String { 21 | switch self { 22 | case .toggleMode: return JS.get() 23 | //case .toggleMode: return getJS(.toggleMode) 24 | } 25 | } 26 | 27 | func getJS(_ script: Script) -> String { 28 | // return script function code 29 | return "" 30 | } 31 | 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Example/WebContent/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #000; 3 | background: #fff; 4 | font-family: -apple-system, BlinkMacSystemFont; 5 | padding: 5px 20px 20px 20px; 6 | } 7 | 8 | /* Apple System Fonts (Deprecated?) 9 | font-family: -apple-system-body 10 | font-family: -apple-system-headline 11 | font-family: -apple-system-subheadline 12 | font-family: -apple-system-caption1 13 | font-family: -apple-system-caption2 14 | font-family: -apple-system-footnote 15 | font-family: -apple-system-short-body 16 | font-family: -apple-system-short-headline 17 | font-family: -apple-system-short-subheadline 18 | font-family: -apple-system-short-caption1 19 | font-family: -apple-system-short-footnote 20 | font-family: -apple-system-tall-body 21 | */ 22 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | async function toggleMode() { 2 | const body = document.querySelector("body"); 3 | 4 | if (!body?.hasAttribute("mode")) { 5 | body?.setAttribute("mode", "light"); 6 | } 7 | 8 | const mode = body?.getAttribute("mode"); 9 | 10 | if (mode == "light") { 11 | body?.style.setProperty("color", "#fff"); 12 | body?.style.setProperty("background", "#000"); 13 | body?.setAttribute("mode", "dark"); 14 | } else { 15 | body?.style.setProperty("color", "#000"); 16 | body?.style.setProperty("background", "#fff"); 17 | body?.setAttribute("mode", "light"); 18 | } 19 | 20 | await new Promise((r) => setTimeout(r, 1000)); 21 | 22 | const result = "Mode: " + body?.getAttribute("mode")?.toString(); 23 | console.log(result); 24 | 25 | // `wekbit` typing comes from `src/types/global.d.ts` 26 | window.webkit.messageHandlers.eventListeners.postMessage(result); 27 | } 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // opinionated rules 4 | "strict": true, 5 | "noImplicitReturns": true, 6 | "noFallthroughCasesInSwitch": true, 7 | "noUnusedLocals": true, 8 | "noUnusedParameters": true, 9 | "allowUnreachableCode": false, 10 | "forceConsistentCasingInFileNames": true, 11 | 12 | // config 13 | "allowJs": true, 14 | "sourceMap": true, 15 | "skipLibCheck": true, 16 | "declaration": true, 17 | "importHelpers": true, 18 | "resolveJsonModule": true, 19 | "moduleResolution": "node", 20 | "module": "commonjs", 21 | "outDir": "dist", 22 | "rootDir": "src", 23 | "target": "es5", 24 | "esModuleInterop": true, 25 | "lib": ["dom", "dom.iterable", "esnext"], 26 | "typeRoots": ["src/types", "node_modules/@types"], 27 | }, 28 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"], 29 | "exclude": ["./node_modules"] 30 | } -------------------------------------------------------------------------------- /Example/macOS/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-19. 6 | // 7 | 8 | import Cocoa 9 | 10 | @main 11 | class AppDelegate: NSObject, NSApplicationDelegate { 12 | 13 | var mainWindow: NSWindow! 14 | @IBOutlet var debugMenu: NSMenuItem! 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | mainWindow = NSApplication.shared.windows[0] 18 | NSApp.activate(ignoringOtherApps: true) 19 | debugMenu.isHidden = !debug 20 | } 21 | 22 | func applicationWillTerminate(_ aNotification: Notification) { 23 | // Insert code here to tear down your application 24 | } 25 | 26 | // Handles Reopening of Main Window 27 | func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { 28 | if !flag { 29 | for window in sender.windows { 30 | window.makeKeyAndOrderFront(self) 31 | } 32 | } 33 | return true 34 | } 35 | 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wktypescript", 3 | "version": "1.0.0", 4 | "description": "A basic framework for evaluating TypeScript through WebKit", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "npx tsc" 8 | }, 9 | "husky": { 10 | "hooks": { 11 | "pre-commit": "lint-staged" 12 | } 13 | }, 14 | "lint-staged": { 15 | "*.{ts,tsx,js,jsx}": [ 16 | "npx prettier --write", 17 | "eslint --cache --fix" 18 | ] 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/inter-ops/WKTypeScript.git" 23 | }, 24 | "author": "Francesco Virga @francescov1", 25 | "license": "ISC", 26 | "bugs": { 27 | "url": "https://github.com/inter-ops/WKTypeScript/issues" 28 | }, 29 | "homepage": "https://github.com/inter-ops/WKTypeScript#readme", 30 | "devDependencies": { 31 | "@typescript-eslint/eslint-plugin": "^4.10.0", 32 | "@typescript-eslint/parser": "^4.10.0", 33 | "eslint": "^7.16.0", 34 | "husky": "^4.3.6", 35 | "lint-staged": "^10.5.3", 36 | "prettier": "^2.2.1", 37 | "typescript": "^4.1.3" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Justin Bush 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Example/macOS/Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Example/macOS/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | 1 23 | LSApplicationCategoryType 24 | public.app-category.developer-tools 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSAllowsArbitraryLoadsForMedia 32 | 33 | NSAllowsArbitraryLoadsInWebContent 34 | 35 | 36 | NSMainStoryboardFile 37 | Main 38 | NSPrincipalClass 39 | NSApplication 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/iOS/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-22. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### This project has been archived. For the modern version of this project, see [TypeSwift](https://github.com/TypeSwift/TypeSwift). 2 | 3 |
4 | 5 | Bridge the gap between TypeScript and Swift – a Node.js generator and WebKit extension framework, all in one. 6 | 7 | # Overview 8 | Declare your functions in TypeScript. Call them, with type-safe parameters, in native Swift. 9 | 10 | 11 | 12 | **WKTypeScript** allows you to automate and streamline your TypeScript-Swift workflow. Go from declaring code in TypeScript, to implementing them in native Swift – with `npm run build` in the middle. 13 | 14 | 15 | 16 | 29 | 30 | ## Evluate in WebView 31 | ```swift 32 | webView.ts(.myVar) 33 | webView.ts(.myFunc()) 34 | webView.ts(.myCallback(.forSomeVal)) { (result) in 35 | switch result { 36 | case success: print("\(success)") 37 | } 38 | } 39 | 40 | ``` 41 | 42 | ### Setup 43 | Setup here. 44 | 45 | ### Building 46 | Building here. 47 | 48 | ## Configuration 49 | Config here. 50 | 51 | ## Progress 52 | - [x] JavaScript type-safe function reference generator for native Swift 53 | - [x] Create example iOS project 54 | - [x] Create example macOS project 55 | - [x] Create cross-platform example project 56 | - [ ] Make a better README *working on it* 57 | 58 | ## Requirements 59 | 60 | ### Swift 61 | - iOS 11 or later 62 | - macOS 10.14 or later 63 | -------------------------------------------------------------------------------- /Example/iOS/Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Example/iOS/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-22. 6 | // 7 | 8 | import UIKit 9 | import WebKit 10 | 11 | /// Enables debug functions and console logs when `true` 12 | let debug = true 13 | 14 | class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler { 15 | 16 | @IBOutlet var webView: WKWebView! 17 | @IBOutlet var toggleModeButton: UIBarButtonItem! 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | initWebView() 22 | } 23 | 24 | // MARK: WebKit Config 25 | /// Initializes the main WKWebView object. 26 | func initWebView() { 27 | webView.uiDelegate = self // Set WebView UI Delegate 28 | webView.navigationDelegate = self // Set WebView Navigation Delegate 29 | // JavaScript Event Listeners 30 | webView.configuration.userContentController.add(self, name: "eventListeners") 31 | webView.load(file: "index", path: "WebContent") 32 | } 33 | /// Clear WebKit WebView object cache. 34 | func clearCache() { 35 | let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache]) 36 | let date = Date(timeIntervalSince1970: 0) 37 | WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set, modifiedSince: date, completionHandler:{ }) 38 | } 39 | 40 | func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { 41 | run(JS.get()) 42 | } 43 | 44 | // MARK: JavaScript Handler 45 | func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { 46 | // JavaScript event listeners 47 | } 48 | 49 | @IBAction func toggleMode(_ sender: UIBarButtonItem) { 50 | run(Script.toggleMode) 51 | } 52 | 53 | } 54 | 55 | // MARK:- WebKit Extension 56 | extension WKWebView { 57 | /// Override WKWebView safe area insets. 58 | override open var safeAreaInsets: UIEdgeInsets { 59 | return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Example/iOS/Example/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | UISupportedInterfaceOrientations~ipad 59 | 60 | UIInterfaceOrientationPortrait 61 | UIInterfaceOrientationPortraitUpsideDown 62 | UIInterfaceOrientationLandscapeLeft 63 | UIInterfaceOrientationLandscapeRight 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Example/macOS/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-19. 6 | // 7 | 8 | import Cocoa 9 | import WebKit 10 | 11 | /// Enables debug functions and console logs when `true` 12 | let debug = true 13 | 14 | class ViewController: NSViewController, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler { 15 | 16 | @IBOutlet var webView: WKWebView! 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | clearCache() 22 | initWebView() 23 | 24 | NotificationCenter.default.addObserver(self, selector: #selector(self.didToggleMode(_:)), name: .didToggleMode, object: nil) 25 | 26 | } 27 | 28 | // MARK: WebKit Config 29 | /// Initializes the main WKWebView object. 30 | func initWebView() { 31 | webView.uiDelegate = self // Set WebView UI Delegate 32 | webView.navigationDelegate = self // Set WebView Navigation Delegate 33 | // JavaScript Event Listeners 34 | webView.configuration.userContentController.add(self, name: "eventListeners") 35 | webView.load(file: "index", path: "WebContent") 36 | } 37 | /// Clear WebKit WebView object cache. 38 | func clearCache() { 39 | let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache]) 40 | let date = Date(timeIntervalSince1970: 0) 41 | WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set, modifiedSince: date, completionHandler:{ }) 42 | } 43 | 44 | func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { 45 | run(JS.get()) 46 | } 47 | 48 | 49 | // MARK: JavaScript Handler 50 | func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { 51 | // JavaScript event listeners 52 | } 53 | 54 | @objc func didToggleMode(_ notification: Notification) { 55 | run("toggleMode();") 56 | } 57 | 58 | 59 | override var representedObject: Any? { 60 | didSet { 61 | // Update the view, if already loaded. 62 | } 63 | } 64 | 65 | 66 | } 67 | 68 | // MARK: Notification Extensions 69 | extension Notification.Name { 70 | static let didToggleMode = Notification.Name("didToggleMode") 71 | } 72 | 73 | -------------------------------------------------------------------------------- /Example/Shared/WebKit/JSManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSManager.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-22. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: JavaScript Manager 11 | /// Handles all of the reading and retrieval of JavaScript content from file. 12 | struct JS { 13 | 14 | static let index = "index" // index.js (default) 15 | static let path = "dist/" // path/to/js 16 | 17 | /// Returns the generated JavaScript code for `index.js` as a String. 18 | static func get() -> String { 19 | return get(file: index, path: path) 20 | } 21 | /// Returns the generated JavaScript code for a specified JavaScript `file`. 22 | /// - parameters: 23 | /// - file: The name of the JavaScript file you wish to retrieve (file extension is optional) 24 | /// - returns: The contents of the input JavaScript file as a String 25 | /// # Usage 26 | /// let code = JS.get(file: "index") 27 | /// webView.evaluateJavaScript(code) 28 | static func get(file: String) -> String { 29 | get(file: file, path: path) 30 | } 31 | /// Returns the generated JavaScript code for a specified JavaScript `file`. 32 | /// - parameters: 33 | /// - file: The name of the JavaScript file you wish to retrieve (file extension is optional) 34 | /// - path: The path to the directory where the JavaScript file is located 35 | /// - returns: The contents of the input JavaScript file as a String 36 | /// # Usage 37 | /// let code = JS.get(file: "index") 38 | /// webView.evaluateJavaScript(code) 39 | static func get(file: String, path: String) -> String { 40 | if let filePath = Bundle.main.path(forResource: "\(path)\(file.removeExtension())", ofType: "js") { 41 | do { 42 | let contents = try String(contentsOfFile: filePath) 43 | return contents 44 | } catch { 45 | print("Error: contents could not be loaded") 46 | } 47 | } else { 48 | print("Error: \(file.removeExtension()).js not found") 49 | } 50 | return "Error" 51 | } 52 | 53 | } 54 | 55 | // MARK: String Extension 56 | extension String { 57 | /// Removes the `.js` extension from the file name (ie. `"index.js" -> "index"`). 58 | func removeExtension() -> String { 59 | return self.replacingOccurrences(of: ".js", with: "") 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Example/iOS/Example/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-22. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 19 | guard let _ = (scene as? UIWindowScene) else { return } 20 | } 21 | 22 | func sceneDidDisconnect(_ scene: UIScene) { 23 | // Called as the scene is being released by the system. 24 | // This occurs shortly after the scene enters the background, or when its session is discarded. 25 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 27 | } 28 | 29 | func sceneDidBecomeActive(_ scene: UIScene) { 30 | // Called when the scene has moved from an inactive state to an active state. 31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 32 | } 33 | 34 | func sceneWillResignActive(_ scene: UIScene) { 35 | // Called when the scene will move from an active state to an inactive state. 36 | // This may occur due to temporary interruptions (ex. an incoming phone call). 37 | } 38 | 39 | func sceneWillEnterForeground(_ scene: UIScene) { 40 | // Called as the scene transitions from the background to the foreground. 41 | // Use this method to undo the changes made on entering the background. 42 | } 43 | 44 | func sceneDidEnterBackground(_ scene: UIScene) { 45 | // Called as the scene transitions from the foreground to the background. 46 | // Use this method to save data, release shared resources, and store enough scene-specific state information 47 | // to restore the scene back to its current state. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/xcshareddata/xcschemes/Example (iOS).xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Example/macOS/Example.xcodeproj/xcshareddata/xcschemes/Example (macOS).xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Example/iOS/Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/Shared/WebKit/WKRunScript.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WKRunScript.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-22. 6 | // 7 | 8 | import Foundation 9 | 10 | var jsReturn = "" // JS Console Response 11 | 12 | // MARK: Run Script 13 | // Run JavaScript in WKWebView and handle return values 14 | extension ViewController { 15 | /// Run JavaScript code in WKWebView with completion handlers `result` and `error` 16 | /// - Parameters: 17 | /// - script: JavaScript code to run (see `Script.swift`) 18 | /// 19 | /// **Enable Console Logs:** `debug = true` 20 | func run(_ script: Script) { 21 | webView.evaluateJavaScript(script.name) { (result, error) in 22 | if let result = result as? String { 23 | if debug { print("Result: \(String(describing: result))") } 24 | } 25 | if error != nil { 26 | if debug { print("Error: \(String(describing: error))") } 27 | } 28 | } 29 | } 30 | /// Run JavaScript code in WKWebView with return completion handler `result` and `error` 31 | /// - Parameters: 32 | /// - script: JavaScript code to run (see `Script.swift`) 33 | /// - Returns: `result` or `error` as String 34 | /// 35 | /// **Enable Console Logs:** `debug = true` 36 | func runWithResult(_ script: Script) -> String { 37 | webView.evaluateJavaScript(script.name) { (result, error) in 38 | if let result = result as? String { 39 | if debug { print("Result: \(String(describing: result))") } 40 | jsReturn = result 41 | } 42 | if error != nil { 43 | if debug { print("Error: \(String(describing: error))") } 44 | } 45 | } 46 | return jsReturn 47 | } 48 | 49 | // MARK:- Deprecated Run Scripts 50 | // Reads input JavaScript as String and executes in WebKit 51 | /// Run JavaScript code in WKWebView with completion handlers `result` and `error` 52 | /// - Parameters: 53 | /// - script: JavaScript code to run (see `Script.swift`) 54 | /// 55 | /// **Enable Console Logs:** `debug = true` 56 | func run(_ script: String) { 57 | webView.evaluateJavaScript(script) { (result, error) in 58 | if let result = result as? String { 59 | if debug { print("Result: \(String(describing: result))") } 60 | } 61 | if error != nil { 62 | if debug { print("Error: \(String(describing: error))") } 63 | } 64 | } 65 | } 66 | /// Run JavaScript code in WKWebView with return completion handler `result` and `error` 67 | /// - Parameters: 68 | /// - script: JavaScript code to run (see `Script.swift`) 69 | /// - Returns: `result` or `error` as String 70 | /// 71 | /// **Enable Console Logs:** `debug = true` 72 | func runWithResult(_ script: String) -> String { 73 | webView.evaluateJavaScript(script) { (result, error) in 74 | if let result = result as? String { 75 | if debug { print("Result: \(String(describing: result))") } 76 | jsReturn = result 77 | } 78 | if error != nil { 79 | if debug { print("Error: \(String(describing: error))") } 80 | } 81 | } 82 | return jsReturn 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /Example/README.md: -------------------------------------------------------------------------------- 1 | # WKTypeScript Example Apps 2 | We have provided two example projects, each running a version of the app optimized for all iOS, iPadOS and macOS platforms. The two projects share the same codebase and present the same web content to be manipulated by the TypeScript code. 3 | 4 | ## Project Hierarchy 5 | - `iOS/`: Example app for iOS and iPadOS 6 | - `macOS/`: Example app for macOS 7 | - `Shared/`: A shared codebase for the iOS, iPadOS and macOS example projects 8 | - `WebContent/`: A shared example web project presented in all example projects 9 | 10 | ## Shared 11 | The shared codebase allows for a number of possibilities, with the three most important being: 12 | 13 | - **[Script.swift](Shared/Script.swift):** A database of TypeScript functions that allow for us to make type-safe calls, to said functions, through native Swift 14 | - **[JSManager.swift](Shared/WebKit/JSManager.swift):** Handles all content retrieval of the compiled JavaScript (`dist/`) 15 | - **[WKRunScript.swift](Shared/WebKit/WKRunScript):** Handles the execution of the compiled JavaScript code through WebKit 16 | 17 | In a brief, the process for running a TypeScript function through some WebKit object: 18 | 19 | 1. Call a TypeScript function from **Script** (type-safe) 20 | 2. **Script** will retrieve the function code via **JSManager** 21 | 3. **WKRunSript**'s `run()` method will execute the JavaScript 22 | 23 | ### [Script.swift](Shared/Script.swift) enum 24 | This is where all of the TypeScript functions are configured and stored in plain text. The Script enum allows for us to make calls to a type-safe function that is located in the generated TypeScript file. 25 | 26 | In the Example apps, we use a TypeScript function, `toggleMode()`, to manipulate the contents of the WKWebView (see [index.ts](https://github.com/inter-ops/WKTypeScript/blob/main/src/index.ts) for the raw code). 27 | 28 | ``` 29 | enum Script { 30 | 31 | case toggleMode 32 | 33 | var name: String { 34 | switch self { 35 | case .toggleMode: return "toggleMode();" 36 | } 37 | } 38 | } 39 | ``` 40 | 41 | Ah! This enum screams high-maintenance! Don't worry... 42 | 43 | Each case, as well as their corresponding values, are automatically generated from functions in the TypeScript file. If you plan on using WKTypeScript as intended, you shouldn't have to ever touch this file. 44 | 45 | The enumerated implementation, however, allows for us to make type-safe calls to raw TypeScript/JavaScript functions in native Swift. 46 | 47 | ``` 48 | func run(script: Script) { 49 | webView.evaluateJavaScript(script.name) 50 | ... 51 | } 52 | ``` 53 | This implementation will allow us to make type-safe calls to TS/JS functions such as: 54 | 55 | ``` 56 | run(script: .toggleMode) 57 | ``` 58 | 59 | A full implementation of [Script.swift](Shared/Script.swift) can be found in the [Shared](Shared/) directory. 60 | 61 | ### [JSManager.swift](Shared/WebKit/JSManager.swift) struct 62 | **JSManager** – shortened to `JS` for quicker access – allows us to retrieve the contents of a compiled JavaScript file and ready it for use with **WKRunScript**. 63 | 64 | Since we are using a TypeScript configuration, we have already set the default file and path: 65 | 66 | ``` 67 | struct JS { 68 | static let index = "index" // index.js (default) 69 | static let path = "dist/" // path/to/js 70 | ... 71 | } 72 | ``` 73 | Where `index.js` and `dist/` are both referenced-to in the example projects, despite being at the root of this repository. 74 | 75 | #### `JS.get()` 76 | 77 | Whether it be for generic use cases, or the desire for all-encompassing functionality compressed into a single file, `JS.get()` is all you need. Once the TypeScript has been transpiled from `index.ts` to `index.js`, this function will return the contents of that compiled JavaScript file at `dist/index.js`. 78 | 79 | #### `JS.get(file: String)` 80 | If you are working with multiple TypeScript files for a more spread-out configuration of your project, this variation will return the contents of the input JavaScript file from within the `dist/` directory. 81 | 82 | #### `JS.get(file: String, path: String)` 83 | Retrieve the contents of any compiled JavaScript file from the specified custom path. 84 | 85 | ### [WKRunScript.swift](Shared/WebKit/WKRunScript.swift) extension 86 | About WKRunScript... 87 | -------------------------------------------------------------------------------- /Example/Shared/Includes/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // Example 4 | // 5 | // Created by Justin Bush on 2020-12-22. 6 | // 7 | 8 | import Foundation 9 | import WebKit 10 | 11 | // MARK: WKWebView 12 | extension WKWebView { 13 | /// Quick and short load URL String in a WKWebView 14 | func load(_ string: String) { 15 | if let url = URL(string: string) { 16 | let request = URLRequest(url: url) 17 | load(request) 18 | } 19 | } 20 | /// Quick and short load URL in a WKWebView 21 | func load(_ url: URL) { 22 | let request = URLRequest(url: url) 23 | load(request) 24 | } 25 | /// Quick load a `file` (without `.html`) and `path` to the directory 26 | /// # Usage 27 | /// webView.loadFile("index", path: "Website") 28 | /// - parameters: 29 | /// - name: Name of the HTML file to load (without `.html`, ie. `"index"`) 30 | /// - path: Path where the HTML file is located (`"website"` for `website/index.html`) 31 | func load(file: String, path: String) { 32 | if let url = Bundle.main.url(forResource: file, withExtension: "html", subdirectory: path) { 33 | self.loadFileURL(url, allowingReadAccessTo: url) 34 | let request = URLRequest(url: url) 35 | load(request) 36 | } 37 | } 38 | /// Quick load a `file` (without `.html`) and `path` to the directory 39 | /// # Usage 40 | /// webView.loadFile("index", path: "Website") 41 | /// - parameters: 42 | /// - name: Name of the HTML file to load (without `.html`, ie. `"index"`) 43 | /// - path: Path where the HTML file is located (`"website"` for `website/index.html`) 44 | func loadFile(_ name: String, path: String) { 45 | if let url = Bundle.main.url(forResource: name, withExtension: "html", subdirectory: path) { 46 | self.loadFileURL(url, allowingReadAccessTo: url) 47 | let request = URLRequest(url: url) 48 | load(request) 49 | } 50 | } 51 | } 52 | 53 | 54 | // MARK: URL 55 | extension URL { 56 | /// Converts `URL` to Optional `String` 57 | func toString() -> String { 58 | return self.absoluteString 59 | } 60 | /// Returns `true` if `URL` is secure 61 | func isSecure() -> Bool { 62 | let string = self.toString() 63 | if string.contains("https://") { return true } 64 | else { return false } 65 | } 66 | } 67 | 68 | 69 | 70 | // MARK: String 71 | extension String { 72 | /// Quick convert `String` to `URL` 73 | /// # Usage 74 | /// let url = String.toURL 75 | func toURL() -> URL { 76 | return URL(string: self)! 77 | } 78 | /// Get the name of a file, from a `Sring`, without path or file extension 79 | /// # Usage 80 | /// let path = "/dir/file.txt" 81 | /// let file = path.fileName() 82 | /// - returns: `"/dir/file.txt" -> "file"` 83 | func fileName() -> String { 84 | return URL(fileURLWithPath: self).deletingPathExtension().lastPathComponent 85 | } 86 | /// Get the extension of a file (`html`, `txt`, etc.), from a `Sring`, without path or name 87 | /// # Usage 88 | /// let name = "index.html" 89 | /// let ext = name.fileExtension() 90 | /// - returns: `"file.txt" -> "txt"` 91 | func fileExtension() -> String { 92 | return URL(fileURLWithPath: self).pathExtension 93 | } 94 | /// Get the file name and extension (`file.txt`), from a `Sring`, without path component 95 | /// # Usage 96 | /// let path = "/path/to/file.txt" 97 | /// let file = path.removePath() 98 | /// - returns: `"/path/to/file.txt" -> "file.txt"` 99 | func removePath() -> String { 100 | return URL(fileURLWithPath: self).lastPathComponent 101 | } 102 | /// Extracts URLs from a `String` and returns them as an `array` of `[URLs]` 103 | /// # Usage 104 | /// let html = [HTML as String] 105 | /// let urls = html.extractURLs() 106 | /// - returns: `["url1", "url2", ...]` 107 | func extractURLs() -> [URL] { 108 | var urls : [URL] = [] 109 | do { 110 | let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) 111 | detector.enumerateMatches(in: self, options: [], range: NSMakeRange(0, self.count), using: { (result, _, _) in 112 | if let match = result, let url = match.url { 113 | urls.append(url) 114 | } 115 | }) 116 | } catch let error as NSError { 117 | print(error.localizedDescription) 118 | } 119 | return urls 120 | } 121 | /// Returns true if the `String` is either empty or only spaces 122 | func isBlank() -> Bool { 123 | if (self.isEmpty) { return true } 124 | return (self.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines) == "") 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Example/iOS/Example/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 | 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 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C207E76A25924E5800A04149 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E76925924E5800A04149 /* AppDelegate.swift */; }; 11 | C207E76C25924E5800A04149 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E76B25924E5800A04149 /* SceneDelegate.swift */; }; 12 | C207E76E25924E5800A04149 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E76D25924E5800A04149 /* ViewController.swift */; }; 13 | C207E77125924E5800A04149 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C207E76F25924E5800A04149 /* Main.storyboard */; }; 14 | C207E77325924E5A00A04149 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C207E77225924E5A00A04149 /* Assets.xcassets */; }; 15 | C207E77625924E5A00A04149 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C207E77425924E5A00A04149 /* LaunchScreen.storyboard */; }; 16 | C207E78D2592555B00A04149 /* WebContent in Resources */ = {isa = PBXBuildFile; fileRef = C207E78C2592555B00A04149 /* WebContent */; }; 17 | C207E7902592557200A04149 /* dist in Resources */ = {isa = PBXBuildFile; fileRef = C207E78F2592557200A04149 /* dist */; }; 18 | C207E7B0259273F600A04149 /* WKRunScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E7AB259273F600A04149 /* WKRunScript.swift */; }; 19 | C207E7B1259273F600A04149 /* JSManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E7AC259273F600A04149 /* JSManager.swift */; }; 20 | C207E7B2259273F600A04149 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E7AE259273F600A04149 /* Extensions.swift */; }; 21 | C207E7B3259273F600A04149 /* Script.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E7AF259273F600A04149 /* Script.swift */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | C207E76625924E5800A04149 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | C207E76925924E5800A04149 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 27 | C207E76B25924E5800A04149 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 28 | C207E76D25924E5800A04149 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 29 | C207E77025924E5800A04149 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 30 | C207E77225924E5A00A04149 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 31 | C207E77525924E5A00A04149 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 32 | C207E77725924E5A00A04149 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | C207E78C2592555B00A04149 /* WebContent */ = {isa = PBXFileReference; lastKnownFileType = folder; name = WebContent; path = ../../WebContent; sourceTree = ""; }; 34 | C207E78F2592557200A04149 /* dist */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dist; path = ../../../dist; sourceTree = ""; }; 35 | C207E7AB259273F600A04149 /* WKRunScript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WKRunScript.swift; sourceTree = ""; }; 36 | C207E7AC259273F600A04149 /* JSManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSManager.swift; sourceTree = ""; }; 37 | C207E7AE259273F600A04149 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 38 | C207E7AF259273F600A04149 /* Script.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Script.swift; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | C207E76325924E5800A04149 /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXFrameworksBuildPhase section */ 50 | 51 | /* Begin PBXGroup section */ 52 | C207E75D25924E5800A04149 = { 53 | isa = PBXGroup; 54 | children = ( 55 | C207E76825924E5800A04149 /* Example */, 56 | C207E76725924E5800A04149 /* Products */, 57 | ); 58 | sourceTree = ""; 59 | }; 60 | C207E76725924E5800A04149 /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | C207E76625924E5800A04149 /* Example.app */, 64 | ); 65 | name = Products; 66 | sourceTree = ""; 67 | }; 68 | C207E76825924E5800A04149 /* Example */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | C207E76925924E5800A04149 /* AppDelegate.swift */, 72 | C207E76B25924E5800A04149 /* SceneDelegate.swift */, 73 | C207E76D25924E5800A04149 /* ViewController.swift */, 74 | C207E7A9259273F600A04149 /* Shared */, 75 | C207E76F25924E5800A04149 /* Main.storyboard */, 76 | C207E77225924E5A00A04149 /* Assets.xcassets */, 77 | C207E77425924E5A00A04149 /* LaunchScreen.storyboard */, 78 | C207E77725924E5A00A04149 /* Info.plist */, 79 | C207E78C2592555B00A04149 /* WebContent */, 80 | C207E78F2592557200A04149 /* dist */, 81 | ); 82 | path = Example; 83 | sourceTree = ""; 84 | }; 85 | C207E7A9259273F600A04149 /* Shared */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | C207E7AF259273F600A04149 /* Script.swift */, 89 | C207E7AA259273F600A04149 /* WebKit */, 90 | C207E7AD259273F600A04149 /* Includes */, 91 | ); 92 | name = Shared; 93 | path = ../../Shared; 94 | sourceTree = ""; 95 | }; 96 | C207E7AA259273F600A04149 /* WebKit */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | C207E7AB259273F600A04149 /* WKRunScript.swift */, 100 | C207E7AC259273F600A04149 /* JSManager.swift */, 101 | ); 102 | path = WebKit; 103 | sourceTree = ""; 104 | }; 105 | C207E7AD259273F600A04149 /* Includes */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | C207E7AE259273F600A04149 /* Extensions.swift */, 109 | ); 110 | path = Includes; 111 | sourceTree = ""; 112 | }; 113 | /* End PBXGroup section */ 114 | 115 | /* Begin PBXNativeTarget section */ 116 | C207E76525924E5800A04149 /* Example */ = { 117 | isa = PBXNativeTarget; 118 | buildConfigurationList = C207E77A25924E5A00A04149 /* Build configuration list for PBXNativeTarget "Example" */; 119 | buildPhases = ( 120 | C207E76225924E5800A04149 /* Sources */, 121 | C207E76325924E5800A04149 /* Frameworks */, 122 | C207E76425924E5800A04149 /* Resources */, 123 | ); 124 | buildRules = ( 125 | ); 126 | dependencies = ( 127 | ); 128 | name = Example; 129 | productName = Example; 130 | productReference = C207E76625924E5800A04149 /* Example.app */; 131 | productType = "com.apple.product-type.application"; 132 | }; 133 | /* End PBXNativeTarget section */ 134 | 135 | /* Begin PBXProject section */ 136 | C207E75E25924E5800A04149 /* Project object */ = { 137 | isa = PBXProject; 138 | attributes = { 139 | LastSwiftUpdateCheck = 1230; 140 | LastUpgradeCheck = 1230; 141 | TargetAttributes = { 142 | C207E76525924E5800A04149 = { 143 | CreatedOnToolsVersion = 12.3; 144 | }; 145 | }; 146 | }; 147 | buildConfigurationList = C207E76125924E5800A04149 /* Build configuration list for PBXProject "Example" */; 148 | compatibilityVersion = "Xcode 9.3"; 149 | developmentRegion = en; 150 | hasScannedForEncodings = 0; 151 | knownRegions = ( 152 | en, 153 | Base, 154 | ); 155 | mainGroup = C207E75D25924E5800A04149; 156 | productRefGroup = C207E76725924E5800A04149 /* Products */; 157 | projectDirPath = ""; 158 | projectRoot = ""; 159 | targets = ( 160 | C207E76525924E5800A04149 /* Example */, 161 | ); 162 | }; 163 | /* End PBXProject section */ 164 | 165 | /* Begin PBXResourcesBuildPhase section */ 166 | C207E76425924E5800A04149 /* Resources */ = { 167 | isa = PBXResourcesBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | C207E77625924E5A00A04149 /* LaunchScreen.storyboard in Resources */, 171 | C207E77325924E5A00A04149 /* Assets.xcassets in Resources */, 172 | C207E7902592557200A04149 /* dist in Resources */, 173 | C207E77125924E5800A04149 /* Main.storyboard in Resources */, 174 | C207E78D2592555B00A04149 /* WebContent in Resources */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXResourcesBuildPhase section */ 179 | 180 | /* Begin PBXSourcesBuildPhase section */ 181 | C207E76225924E5800A04149 /* Sources */ = { 182 | isa = PBXSourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | C207E7B0259273F600A04149 /* WKRunScript.swift in Sources */, 186 | C207E7B3259273F600A04149 /* Script.swift in Sources */, 187 | C207E7B2259273F600A04149 /* Extensions.swift in Sources */, 188 | C207E76E25924E5800A04149 /* ViewController.swift in Sources */, 189 | C207E76A25924E5800A04149 /* AppDelegate.swift in Sources */, 190 | C207E76C25924E5800A04149 /* SceneDelegate.swift in Sources */, 191 | C207E7B1259273F600A04149 /* JSManager.swift in Sources */, 192 | ); 193 | runOnlyForDeploymentPostprocessing = 0; 194 | }; 195 | /* End PBXSourcesBuildPhase section */ 196 | 197 | /* Begin PBXVariantGroup section */ 198 | C207E76F25924E5800A04149 /* Main.storyboard */ = { 199 | isa = PBXVariantGroup; 200 | children = ( 201 | C207E77025924E5800A04149 /* Base */, 202 | ); 203 | name = Main.storyboard; 204 | sourceTree = ""; 205 | }; 206 | C207E77425924E5A00A04149 /* LaunchScreen.storyboard */ = { 207 | isa = PBXVariantGroup; 208 | children = ( 209 | C207E77525924E5A00A04149 /* Base */, 210 | ); 211 | name = LaunchScreen.storyboard; 212 | sourceTree = ""; 213 | }; 214 | /* End PBXVariantGroup section */ 215 | 216 | /* Begin XCBuildConfiguration section */ 217 | C207E77825924E5A00A04149 /* Debug */ = { 218 | isa = XCBuildConfiguration; 219 | buildSettings = { 220 | ALWAYS_SEARCH_USER_PATHS = NO; 221 | CLANG_ANALYZER_NONNULL = YES; 222 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 223 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 224 | CLANG_CXX_LIBRARY = "libc++"; 225 | CLANG_ENABLE_MODULES = YES; 226 | CLANG_ENABLE_OBJC_ARC = YES; 227 | CLANG_ENABLE_OBJC_WEAK = YES; 228 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 229 | CLANG_WARN_BOOL_CONVERSION = YES; 230 | CLANG_WARN_COMMA = YES; 231 | CLANG_WARN_CONSTANT_CONVERSION = YES; 232 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 233 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 234 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 235 | CLANG_WARN_EMPTY_BODY = YES; 236 | CLANG_WARN_ENUM_CONVERSION = YES; 237 | CLANG_WARN_INFINITE_RECURSION = YES; 238 | CLANG_WARN_INT_CONVERSION = YES; 239 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 241 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 242 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 243 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 244 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 245 | CLANG_WARN_STRICT_PROTOTYPES = YES; 246 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 247 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 248 | CLANG_WARN_UNREACHABLE_CODE = YES; 249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 250 | COPY_PHASE_STRIP = NO; 251 | DEBUG_INFORMATION_FORMAT = dwarf; 252 | ENABLE_STRICT_OBJC_MSGSEND = YES; 253 | ENABLE_TESTABILITY = YES; 254 | GCC_C_LANGUAGE_STANDARD = gnu11; 255 | GCC_DYNAMIC_NO_PIC = NO; 256 | GCC_NO_COMMON_BLOCKS = YES; 257 | GCC_OPTIMIZATION_LEVEL = 0; 258 | GCC_PREPROCESSOR_DEFINITIONS = ( 259 | "DEBUG=1", 260 | "$(inherited)", 261 | ); 262 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 263 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 264 | GCC_WARN_UNDECLARED_SELECTOR = YES; 265 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 266 | GCC_WARN_UNUSED_FUNCTION = YES; 267 | GCC_WARN_UNUSED_VARIABLE = YES; 268 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 269 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 270 | MTL_FAST_MATH = YES; 271 | ONLY_ACTIVE_ARCH = YES; 272 | SDKROOT = iphoneos; 273 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 274 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 275 | }; 276 | name = Debug; 277 | }; 278 | C207E77925924E5A00A04149 /* Release */ = { 279 | isa = XCBuildConfiguration; 280 | buildSettings = { 281 | ALWAYS_SEARCH_USER_PATHS = NO; 282 | CLANG_ANALYZER_NONNULL = YES; 283 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 284 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 285 | CLANG_CXX_LIBRARY = "libc++"; 286 | CLANG_ENABLE_MODULES = YES; 287 | CLANG_ENABLE_OBJC_ARC = YES; 288 | CLANG_ENABLE_OBJC_WEAK = YES; 289 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 290 | CLANG_WARN_BOOL_CONVERSION = YES; 291 | CLANG_WARN_COMMA = YES; 292 | CLANG_WARN_CONSTANT_CONVERSION = YES; 293 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 294 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 295 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 296 | CLANG_WARN_EMPTY_BODY = YES; 297 | CLANG_WARN_ENUM_CONVERSION = YES; 298 | CLANG_WARN_INFINITE_RECURSION = YES; 299 | CLANG_WARN_INT_CONVERSION = YES; 300 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 301 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 302 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 303 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 304 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 305 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 306 | CLANG_WARN_STRICT_PROTOTYPES = YES; 307 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 308 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 309 | CLANG_WARN_UNREACHABLE_CODE = YES; 310 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 311 | COPY_PHASE_STRIP = NO; 312 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 313 | ENABLE_NS_ASSERTIONS = NO; 314 | ENABLE_STRICT_OBJC_MSGSEND = YES; 315 | GCC_C_LANGUAGE_STANDARD = gnu11; 316 | GCC_NO_COMMON_BLOCKS = YES; 317 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 318 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 319 | GCC_WARN_UNDECLARED_SELECTOR = YES; 320 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 321 | GCC_WARN_UNUSED_FUNCTION = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 324 | MTL_ENABLE_DEBUG_INFO = NO; 325 | MTL_FAST_MATH = YES; 326 | SDKROOT = iphoneos; 327 | SWIFT_COMPILATION_MODE = wholemodule; 328 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 329 | VALIDATE_PRODUCT = YES; 330 | }; 331 | name = Release; 332 | }; 333 | C207E77B25924E5A00A04149 /* Debug */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 337 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 338 | CODE_SIGN_STYLE = Automatic; 339 | DEVELOPMENT_TEAM = 85N3S3DG8M; 340 | INFOPLIST_FILE = Example/Info.plist; 341 | LD_RUNPATH_SEARCH_PATHS = ( 342 | "$(inherited)", 343 | "@executable_path/Frameworks", 344 | ); 345 | MARKETING_VERSION = 0.0.1; 346 | PRODUCT_BUNDLE_IDENTIFIER = com.interops.Example; 347 | PRODUCT_NAME = "$(TARGET_NAME)"; 348 | SWIFT_VERSION = 5.0; 349 | TARGETED_DEVICE_FAMILY = "1,2"; 350 | }; 351 | name = Debug; 352 | }; 353 | C207E77C25924E5A00A04149 /* Release */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 358 | CODE_SIGN_STYLE = Automatic; 359 | DEVELOPMENT_TEAM = 85N3S3DG8M; 360 | INFOPLIST_FILE = Example/Info.plist; 361 | LD_RUNPATH_SEARCH_PATHS = ( 362 | "$(inherited)", 363 | "@executable_path/Frameworks", 364 | ); 365 | MARKETING_VERSION = 0.0.1; 366 | PRODUCT_BUNDLE_IDENTIFIER = com.interops.Example; 367 | PRODUCT_NAME = "$(TARGET_NAME)"; 368 | SWIFT_VERSION = 5.0; 369 | TARGETED_DEVICE_FAMILY = "1,2"; 370 | }; 371 | name = Release; 372 | }; 373 | /* End XCBuildConfiguration section */ 374 | 375 | /* Begin XCConfigurationList section */ 376 | C207E76125924E5800A04149 /* Build configuration list for PBXProject "Example" */ = { 377 | isa = XCConfigurationList; 378 | buildConfigurations = ( 379 | C207E77825924E5A00A04149 /* Debug */, 380 | C207E77925924E5A00A04149 /* Release */, 381 | ); 382 | defaultConfigurationIsVisible = 0; 383 | defaultConfigurationName = Release; 384 | }; 385 | C207E77A25924E5A00A04149 /* Build configuration list for PBXNativeTarget "Example" */ = { 386 | isa = XCConfigurationList; 387 | buildConfigurations = ( 388 | C207E77B25924E5A00A04149 /* Debug */, 389 | C207E77C25924E5A00A04149 /* Release */, 390 | ); 391 | defaultConfigurationIsVisible = 0; 392 | defaultConfigurationName = Release; 393 | }; 394 | /* End XCConfigurationList section */ 395 | }; 396 | rootObject = C207E75E25924E5800A04149 /* Project object */; 397 | } 398 | -------------------------------------------------------------------------------- /Example/macOS/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C207E7A12592732700A04149 /* WKRunScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E79C2592732700A04149 /* WKRunScript.swift */; }; 11 | C207E7A22592732700A04149 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E79E2592732700A04149 /* Extensions.swift */; }; 12 | C207E7A32592732700A04149 /* JSManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E79F2592732700A04149 /* JSManager.swift */; }; 13 | C207E7A42592732700A04149 /* Script.swift in Sources */ = {isa = PBXBuildFile; fileRef = C207E7A02592732700A04149 /* Script.swift */; }; 14 | C286AC232591291F00A16965 /* dist in Resources */ = {isa = PBXBuildFile; fileRef = C286AC222591291F00A16965 /* dist */; }; 15 | C286AC2625912BA400A16965 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C286AC2525912BA400A16965 /* WindowController.swift */; }; 16 | C286AC302591388500A16965 /* WebContent in Resources */ = {isa = PBXBuildFile; fileRef = C286AC2F2591388500A16965 /* WebContent */; }; 17 | C2C0A68A258E7A680038A67C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2C0A689258E7A680038A67C /* AppDelegate.swift */; }; 18 | C2C0A68C258E7A680038A67C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2C0A68B258E7A680038A67C /* ViewController.swift */; }; 19 | C2C0A68E258E7A690038A67C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C2C0A68D258E7A690038A67C /* Assets.xcassets */; }; 20 | C2C0A691258E7A690038A67C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C2C0A68F258E7A690038A67C /* Main.storyboard */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXBuildRule section */ 24 | C286AC3825914FFD00A16965 /* PBXBuildRule */ = { 25 | isa = PBXBuildRule; 26 | compilerSpec = com.apple.compilers.proxy.script; 27 | fileType = pattern.proxy; 28 | inputFiles = ( 29 | ); 30 | isEditable = 1; 31 | name = "NPM Run Build"; 32 | outputFiles = ( 33 | ); 34 | script = "# Type a script or drag a script file from your workspace to insert its path.\nnpm run build\n"; 35 | }; 36 | /* End PBXBuildRule section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | C207E79C2592732700A04149 /* WKRunScript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WKRunScript.swift; sourceTree = ""; }; 40 | C207E79E2592732700A04149 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 41 | C207E79F2592732700A04149 /* JSManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSManager.swift; sourceTree = ""; }; 42 | C207E7A02592732700A04149 /* Script.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Script.swift; sourceTree = ""; }; 43 | C286AC222591291F00A16965 /* dist */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dist; path = ../../../dist; sourceTree = ""; }; 44 | C286AC2525912BA400A16965 /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; }; 45 | C286AC2F2591388500A16965 /* WebContent */ = {isa = PBXFileReference; lastKnownFileType = folder; name = WebContent; path = ../../WebContent; sourceTree = ""; }; 46 | C2C0A686258E7A680038A67C /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | C2C0A689258E7A680038A67C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 48 | C2C0A68B258E7A680038A67C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 49 | C2C0A68D258E7A690038A67C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | C2C0A690258E7A690038A67C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | C2C0A692258E7A690038A67C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | C2C0A693258E7A690038A67C /* Example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Example.entitlements; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | C2C0A683258E7A680038A67C /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | C207E79B2592732700A04149 /* Shared */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | C207E7A02592732700A04149 /* Script.swift */, 70 | C207E7A72592738700A04149 /* WebKit */, 71 | C207E79D2592732700A04149 /* Includes */, 72 | ); 73 | name = Shared; 74 | path = ../../Shared; 75 | sourceTree = ""; 76 | }; 77 | C207E79D2592732700A04149 /* Includes */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | C207E79E2592732700A04149 /* Extensions.swift */, 81 | ); 82 | path = Includes; 83 | sourceTree = ""; 84 | }; 85 | C207E7A72592738700A04149 /* WebKit */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | C207E79F2592732700A04149 /* JSManager.swift */, 89 | C207E79C2592732700A04149 /* WKRunScript.swift */, 90 | ); 91 | path = WebKit; 92 | sourceTree = ""; 93 | }; 94 | C2C0A67D258E7A680038A67C = { 95 | isa = PBXGroup; 96 | children = ( 97 | C2C0A688258E7A680038A67C /* Example */, 98 | C2C0A687258E7A680038A67C /* Products */, 99 | ); 100 | sourceTree = ""; 101 | }; 102 | C2C0A687258E7A680038A67C /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | C2C0A686258E7A680038A67C /* Example.app */, 106 | ); 107 | name = Products; 108 | sourceTree = ""; 109 | }; 110 | C2C0A688258E7A680038A67C /* Example */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | C2C0A689258E7A680038A67C /* AppDelegate.swift */, 114 | C286AC2525912BA400A16965 /* WindowController.swift */, 115 | C2C0A68B258E7A680038A67C /* ViewController.swift */, 116 | C207E79B2592732700A04149 /* Shared */, 117 | C2C0A68D258E7A690038A67C /* Assets.xcassets */, 118 | C2C0A68F258E7A690038A67C /* Main.storyboard */, 119 | C2C0A692258E7A690038A67C /* Info.plist */, 120 | C2C0A693258E7A690038A67C /* Example.entitlements */, 121 | C286AC2F2591388500A16965 /* WebContent */, 122 | C286AC222591291F00A16965 /* dist */, 123 | ); 124 | path = Example; 125 | sourceTree = ""; 126 | }; 127 | /* End PBXGroup section */ 128 | 129 | /* Begin PBXNativeTarget section */ 130 | C2C0A685258E7A680038A67C /* Example */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = C2C0A696258E7A690038A67C /* Build configuration list for PBXNativeTarget "Example" */; 133 | buildPhases = ( 134 | C2C0A682258E7A680038A67C /* Sources */, 135 | C2C0A683258E7A680038A67C /* Frameworks */, 136 | C2C0A684258E7A680038A67C /* Resources */, 137 | ); 138 | buildRules = ( 139 | C286AC3825914FFD00A16965 /* PBXBuildRule */, 140 | ); 141 | dependencies = ( 142 | ); 143 | name = Example; 144 | productName = Example; 145 | productReference = C2C0A686258E7A680038A67C /* Example.app */; 146 | productType = "com.apple.product-type.application"; 147 | }; 148 | /* End PBXNativeTarget section */ 149 | 150 | /* Begin PBXProject section */ 151 | C2C0A67E258E7A680038A67C /* Project object */ = { 152 | isa = PBXProject; 153 | attributes = { 154 | LastSwiftUpdateCheck = 1230; 155 | LastUpgradeCheck = 1230; 156 | TargetAttributes = { 157 | C2C0A685258E7A680038A67C = { 158 | CreatedOnToolsVersion = 12.3; 159 | }; 160 | }; 161 | }; 162 | buildConfigurationList = C2C0A681258E7A680038A67C /* Build configuration list for PBXProject "Example" */; 163 | compatibilityVersion = "Xcode 9.3"; 164 | developmentRegion = en; 165 | hasScannedForEncodings = 0; 166 | knownRegions = ( 167 | en, 168 | Base, 169 | ); 170 | mainGroup = C2C0A67D258E7A680038A67C; 171 | productRefGroup = C2C0A687258E7A680038A67C /* Products */; 172 | projectDirPath = ""; 173 | projectRoot = ""; 174 | targets = ( 175 | C2C0A685258E7A680038A67C /* Example */, 176 | ); 177 | }; 178 | /* End PBXProject section */ 179 | 180 | /* Begin PBXResourcesBuildPhase section */ 181 | C2C0A684258E7A680038A67C /* Resources */ = { 182 | isa = PBXResourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | C286AC232591291F00A16965 /* dist in Resources */, 186 | C2C0A68E258E7A690038A67C /* Assets.xcassets in Resources */, 187 | C2C0A691258E7A690038A67C /* Main.storyboard in Resources */, 188 | C286AC302591388500A16965 /* WebContent in Resources */, 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | /* End PBXResourcesBuildPhase section */ 193 | 194 | /* Begin PBXSourcesBuildPhase section */ 195 | C2C0A682258E7A680038A67C /* Sources */ = { 196 | isa = PBXSourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | C207E7A32592732700A04149 /* JSManager.swift in Sources */, 200 | C207E7A42592732700A04149 /* Script.swift in Sources */, 201 | C207E7A22592732700A04149 /* Extensions.swift in Sources */, 202 | C207E7A12592732700A04149 /* WKRunScript.swift in Sources */, 203 | C2C0A68C258E7A680038A67C /* ViewController.swift in Sources */, 204 | C286AC2625912BA400A16965 /* WindowController.swift in Sources */, 205 | C2C0A68A258E7A680038A67C /* AppDelegate.swift in Sources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXSourcesBuildPhase section */ 210 | 211 | /* Begin PBXVariantGroup section */ 212 | C2C0A68F258E7A690038A67C /* Main.storyboard */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | C2C0A690258E7A690038A67C /* Base */, 216 | ); 217 | name = Main.storyboard; 218 | sourceTree = ""; 219 | }; 220 | /* End PBXVariantGroup section */ 221 | 222 | /* Begin XCBuildConfiguration section */ 223 | C2C0A694258E7A690038A67C /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = NO; 227 | CLANG_ANALYZER_NONNULL = YES; 228 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 229 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 230 | CLANG_CXX_LIBRARY = "libc++"; 231 | CLANG_ENABLE_MODULES = YES; 232 | CLANG_ENABLE_OBJC_ARC = YES; 233 | CLANG_ENABLE_OBJC_WEAK = YES; 234 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 235 | CLANG_WARN_BOOL_CONVERSION = YES; 236 | CLANG_WARN_COMMA = YES; 237 | CLANG_WARN_CONSTANT_CONVERSION = YES; 238 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 239 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 240 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 241 | CLANG_WARN_EMPTY_BODY = YES; 242 | CLANG_WARN_ENUM_CONVERSION = YES; 243 | CLANG_WARN_INFINITE_RECURSION = YES; 244 | CLANG_WARN_INT_CONVERSION = YES; 245 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 246 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 247 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 248 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 249 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 250 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 251 | CLANG_WARN_STRICT_PROTOTYPES = YES; 252 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 253 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 254 | CLANG_WARN_UNREACHABLE_CODE = YES; 255 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 256 | COPY_PHASE_STRIP = NO; 257 | DEBUG_INFORMATION_FORMAT = dwarf; 258 | ENABLE_STRICT_OBJC_MSGSEND = YES; 259 | ENABLE_TESTABILITY = YES; 260 | GCC_C_LANGUAGE_STANDARD = gnu11; 261 | GCC_DYNAMIC_NO_PIC = NO; 262 | GCC_NO_COMMON_BLOCKS = YES; 263 | GCC_OPTIMIZATION_LEVEL = 0; 264 | GCC_PREPROCESSOR_DEFINITIONS = ( 265 | "DEBUG=1", 266 | "$(inherited)", 267 | ); 268 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 269 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 270 | GCC_WARN_UNDECLARED_SELECTOR = YES; 271 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 272 | GCC_WARN_UNUSED_FUNCTION = YES; 273 | GCC_WARN_UNUSED_VARIABLE = YES; 274 | MACOSX_DEPLOYMENT_TARGET = 11.1; 275 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 276 | MTL_FAST_MATH = YES; 277 | ONLY_ACTIVE_ARCH = YES; 278 | SDKROOT = macosx; 279 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 280 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 281 | }; 282 | name = Debug; 283 | }; 284 | C2C0A695258E7A690038A67C /* Release */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | ALWAYS_SEARCH_USER_PATHS = NO; 288 | CLANG_ANALYZER_NONNULL = YES; 289 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 290 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 291 | CLANG_CXX_LIBRARY = "libc++"; 292 | CLANG_ENABLE_MODULES = YES; 293 | CLANG_ENABLE_OBJC_ARC = YES; 294 | CLANG_ENABLE_OBJC_WEAK = YES; 295 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 296 | CLANG_WARN_BOOL_CONVERSION = YES; 297 | CLANG_WARN_COMMA = YES; 298 | CLANG_WARN_CONSTANT_CONVERSION = YES; 299 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 301 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 302 | CLANG_WARN_EMPTY_BODY = YES; 303 | CLANG_WARN_ENUM_CONVERSION = YES; 304 | CLANG_WARN_INFINITE_RECURSION = YES; 305 | CLANG_WARN_INT_CONVERSION = YES; 306 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 307 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 308 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 309 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 310 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 311 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 312 | CLANG_WARN_STRICT_PROTOTYPES = YES; 313 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 314 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 315 | CLANG_WARN_UNREACHABLE_CODE = YES; 316 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 317 | COPY_PHASE_STRIP = NO; 318 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 319 | ENABLE_NS_ASSERTIONS = NO; 320 | ENABLE_STRICT_OBJC_MSGSEND = YES; 321 | GCC_C_LANGUAGE_STANDARD = gnu11; 322 | GCC_NO_COMMON_BLOCKS = YES; 323 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 324 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 325 | GCC_WARN_UNDECLARED_SELECTOR = YES; 326 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 327 | GCC_WARN_UNUSED_FUNCTION = YES; 328 | GCC_WARN_UNUSED_VARIABLE = YES; 329 | MACOSX_DEPLOYMENT_TARGET = 11.1; 330 | MTL_ENABLE_DEBUG_INFO = NO; 331 | MTL_FAST_MATH = YES; 332 | SDKROOT = macosx; 333 | SWIFT_COMPILATION_MODE = wholemodule; 334 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 335 | }; 336 | name = Release; 337 | }; 338 | C2C0A697258E7A690038A67C /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 342 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 343 | CODE_SIGN_ENTITLEMENTS = Example/Example.entitlements; 344 | CODE_SIGN_STYLE = Automatic; 345 | COMBINE_HIDPI_IMAGES = YES; 346 | DEVELOPMENT_TEAM = 85N3S3DG8M; 347 | ENABLE_HARDENED_RUNTIME = YES; 348 | INFOPLIST_FILE = Example/Info.plist; 349 | LD_RUNPATH_SEARCH_PATHS = ( 350 | "$(inherited)", 351 | "@executable_path/../Frameworks", 352 | ); 353 | MACOSX_DEPLOYMENT_TARGET = 10.14; 354 | MARKETING_VERSION = 0.0.1; 355 | PRODUCT_BUNDLE_IDENTIFIER = com.interops.Example; 356 | PRODUCT_NAME = "$(TARGET_NAME)"; 357 | SWIFT_VERSION = 5.0; 358 | }; 359 | name = Debug; 360 | }; 361 | C2C0A698258E7A690038A67C /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 365 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 366 | CODE_SIGN_ENTITLEMENTS = Example/Example.entitlements; 367 | CODE_SIGN_STYLE = Automatic; 368 | COMBINE_HIDPI_IMAGES = YES; 369 | DEVELOPMENT_TEAM = 85N3S3DG8M; 370 | ENABLE_HARDENED_RUNTIME = YES; 371 | INFOPLIST_FILE = Example/Info.plist; 372 | LD_RUNPATH_SEARCH_PATHS = ( 373 | "$(inherited)", 374 | "@executable_path/../Frameworks", 375 | ); 376 | MACOSX_DEPLOYMENT_TARGET = 10.14; 377 | MARKETING_VERSION = 0.0.1; 378 | PRODUCT_BUNDLE_IDENTIFIER = com.interops.Example; 379 | PRODUCT_NAME = "$(TARGET_NAME)"; 380 | SWIFT_VERSION = 5.0; 381 | }; 382 | name = Release; 383 | }; 384 | /* End XCBuildConfiguration section */ 385 | 386 | /* Begin XCConfigurationList section */ 387 | C2C0A681258E7A680038A67C /* Build configuration list for PBXProject "Example" */ = { 388 | isa = XCConfigurationList; 389 | buildConfigurations = ( 390 | C2C0A694258E7A690038A67C /* Debug */, 391 | C2C0A695258E7A690038A67C /* Release */, 392 | ); 393 | defaultConfigurationIsVisible = 0; 394 | defaultConfigurationName = Release; 395 | }; 396 | C2C0A696258E7A690038A67C /* Build configuration list for PBXNativeTarget "Example" */ = { 397 | isa = XCConfigurationList; 398 | buildConfigurations = ( 399 | C2C0A697258E7A690038A67C /* Debug */, 400 | C2C0A698258E7A690038A67C /* Release */, 401 | ); 402 | defaultConfigurationIsVisible = 0; 403 | defaultConfigurationName = Release; 404 | }; 405 | /* End XCConfigurationList section */ 406 | }; 407 | rootObject = C2C0A67E258E7A680038A67C /* Project object */; 408 | } 409 | -------------------------------------------------------------------------------- /Example/macOS/Example/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 | 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 | Default 532 | 533 | 534 | 535 | 536 | 537 | 538 | Left to Right 539 | 540 | 541 | 542 | 543 | 544 | 545 | Right to Left 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | Default 557 | 558 | 559 | 560 | 561 | 562 | 563 | Left to Right 564 | 565 | 566 | 567 | 568 | 569 | 570 | Right to Left 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | --------------------------------------------------------------------------------