### Install Android Home SDK Source: https://skip.dev/docs/skip-cli Set up the base Android SDK, including cmdline-tools, platform-tools, and the emulator component, in your `ANDROID_HOME` directory. This is typically a one-time setup. ```bash skip android home install ``` -------------------------------- ### CI/CD Android Setup and Test Execution Source: https://skip.dev/docs/skip-cli A typical CI/CD setup involves installing Skip and the Android SDK, creating an emulator, launching it in the background, and then running tests. The emulator launch command waits for the device to boot before returning. ```bash # Install Skip and the Android SDK brew install skiptools/skip/skip skip android sdk install skip android emulator create # Launch an emulator in the background (headless, waits for boot) skip android emulator launch --background --headless # Run tests skip android test ``` -------------------------------- ### Install Skip and Android SDK Source: https://skip.dev/docs/porting Install the Skip toolchain and the native Android SDK using Homebrew. This is the initial setup step for building Swift packages on Android. ```bash $ brew install skiptools/skip $ brew install skiptools/skip/skip … skip was successfully installed! $ skip android sdk install [✓] Install Swift Android SDK (2.4s) ``` -------------------------------- ### Example settings.gradle.kts for Custom Repositories Source: https://skip.dev/docs/dependencies This is an example of a generated `settings.gradle.kts` file that includes custom repositories. Edits to this file will be overwritten. ```kotlin // This is the top-level Gradle settings for the project. // The module dependencies it contains may be symbolic links to peer folders. // // This file is generated by the Skip transpiler plugin and is // derived from the aggregate Skip/skip.yml files from the SwiftPM project. // Edits made directly to this file will be overwritten. // // Open with External Editor to build and run this project in an IDE. // pluginManagement { repositories { gradlePluginPortal() mavenCentral() google() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() google() maven("https://github.com/jectivex/jsc-android/raw/main/releases") } } rootProject.name = "skip.script" include(":SkipScript") include(":SkipFoundation") include(":SkipLib") include(":SkipUnit") include(":SkipFFI") ``` -------------------------------- ### Install Skip Tool Source: https://skip.dev/docs/gettingstarted Installs the Skip tool and necessary build dependencies like the Android SDK and Gradle. Run this after setting up Homebrew. ```bash brew tap skiptools/skip brew install skip ``` -------------------------------- ### Example build.gradle.kts with Dependencies Source: https://skip.dev/docs/dependencies This is an example of a generated `build.gradle.kts` file. It aggregates dependencies from SkipScript and its modules. Edits to this file will be overwritten. ```kotlin // build.gradle.kts generated by Skip for the SkipScript module. // This file is generated by the Skip transpiler plugin and is // derived from the aggregate Skip/skip.yml files from the SwiftPM project. // Edits made directly to this file will be overwritten. dependencies { testImplementation("org.json:json:20180813") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3") androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3") testImplementation("org.robolectric:robolectric:4.10.3") androidTestImplementation("androidx.test:runner:1.5.2") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") androidTestImplementation("org.jetbrains.kotlin:kotlin-test-junit") testImplementation("androidx.test:core:1.5.0") androidTestImplementation("androidx.test:core:1.5.0") testImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.ext:junit:1.1.5") implementation("net.java.dev.jna:jna:5.13.0@aar") testImplementation("net.java.dev.jna:jna:5.13.0") implementation("org.webkit:android-jsc-cppruntime:r245459@aar") implementation("org.webkit:android-jsc:r245459@aar") implementation(project(":SkipFoundation")) implementation(project(":SkipLib")) testImplementation(project(":SkipUnit")) androidTestImplementation(project(":SkipUnit")) implementation(project(":SkipFFI")) } plugins { kotlin("android") version "1.9.0" id("com.android.library") version "8.1.0" } kotlin { jvmToolchain(17) } android { namespace = group as String compileSdk = 34 defaultConfig { minSdk = 29 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" } testOptions { unitTests { isIncludeAndroidResources = true } } } tasks.withType() { kotlinOptions { suppressWarnings = true } } tasks.withType().configureEach { systemProperties.put("robolectric.logging", "stdout") systemProperties.put("robolectric.graphicsMode", "NATIVE") testLogging { this.showStandardStreams = true } } ``` -------------------------------- ### Check Skip Installation and Prerequisites Source: https://skip.dev/docs/gettingstarted Verifies that Skip and its development prerequisites are correctly installed and configured. Use the --verbose flag for detailed output if issues arise. ```bash skip checkup ``` -------------------------------- ### Install Skip using Homebrew Source: https://skip.dev/docs/modules/skip-qrcode Install the Skip toolchain using Homebrew. This command taps the official Skip tools repository and then installs the Skip package. ```bash brew tap skiptools/skip brew install skiptools/skip/skip ``` -------------------------------- ### Install Skip CLI Source: https://skip.dev/docs/skip-cli Installs the Skip CLI tool and necessary Android SDK dependencies using Homebrew. ```bash brew install skiptools/skip/skip ``` -------------------------------- ### Rebuild, Relaunch, and Install Android App Source: https://skip.dev/docs/samples/skipapp-travelposters-native Export the shared Swift model to the Android debug library, install the debug version of the app, and then launch it. ```bash skip export --project travel-posters-model -d Android/lib/debug/ --debug grade -p Android installDebug adb shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n tools.skip.travelposters/tools.skip.travelposters.MainActivity ``` -------------------------------- ### SwiftUI Stack Layout Example Source: https://skip.dev/docs/components/stack This example demonstrates various SwiftUI Stack configurations including HStack, VStack, and ZStack. It shows how elements align and size within these stacks, with borders to visualize boundaries. Use this to understand basic layout principles. ```swift import SwiftUI struct StackPlayground: View { var body: some View { ScrollView { VStack(spacing: 16.0) { HStack { Text("Before fixed") .border(Color.blue) HStack { Spacer() Text("After expanding") } .border(Color.red) Text("After fixed") .border(Color.blue) } VStack { Text("Text1") Text("Text2") } .border(Color.blue) Text("Sized to content:") VStack(spacing: 0.0) { Color.red.frame(width: 50.0, height: 50.0) Color.green.frame(width: 50.0, height: 50.0) } .border(Color.blue) Text("Content sizes to stack:") VStack(spacing: 0.0) { Color.red Color.green } .frame(width: 50.0, height: 100.0) .border(Color.blue) VStack { Text("Text1") Color.green.frame(width: 50.0, height: 50.0) } .border(Color.blue) VStack { Color.red.frame(width: 50.0, height: 50.0) Text("Text2") } .border(Color.blue) VStack(content: horizontalStripes) .background(.yellow) .frame(width: 100.0, height: 100.0) HStack(content: verticalStripes) .background(.yellow) .frame(width: 100.0, height: 100.0) ZStack { Color.yellow Color.red.padding(25.0) } .frame(width: 100.0, height: 100.0) } .padding() } .toolbar { PlaygroundSourceLink(file: "StackPlayground.swift") } } // Note: these functions are also a test that we can pass functions to SwiftUI content view builders. @ViewBuilder private func horizontalStripes() -> some View { Spacer() Color.red.frame(height: 20.0) Spacer() Color.red.frame(height: 20.0) Spacer() } @ViewBuilder private func verticalStripes() -> some View { Spacer() Color.red.frame(width: 20.0) Spacer() Color.red.frame(width: 20.0) Spacer() } } ``` -------------------------------- ### Initialize PostHog SDK Source: https://skip.dev/docs/modules/skip-posthog Set up the PostHog SDK with your project's API key when your application starts. ```swift import SkipPostHog PostHogSDK.shared.setup( PostHogConfig(apiKey: "phc_your_project_api_key") ) ``` ```swift PostHogSDK.shared.setup( PostHogConfig(apiKey: "phc_your_project_api_key", host: "https://your-posthog-instance.com") ) ``` -------------------------------- ### Example Package.swift for Native App Source: https://skip.dev/docs/modes Illustrates the dependencies and targets for a native Skip application with separate model and logic modules. ```swift import PackageDescription let package = Package( name: "skipapp-hiya", defaultLocalization: "en", platforms: [.iOS(.v17), .macOS(.v14), .tvOS(.v17), .watchOS(.v10), .macCatalyst(.v17)], products: [ .library(name: "HiyaSkipApp", type: .dynamic, targets: ["HiyaSkip"]), .library(name: "HiyaSkipModel", type: .dynamic, targets: ["HiyaSkipModel"]), .library(name: "HiyaSkipLogic", type: .dynamic, targets: ["HiyaSkipLogic"]), ], dependencies: [ .package(url: "https://source.skip.tools/skip.git", from: "1.2.7"), .package(url: "https://source.skip.tools/skip-model.git", from: "1.0.0"), .package(url: "https://source.skip.tools/skip-fuse.git", from: "1.0.0"), .package(url: "https://source.skip.tools/skip-fuse-ui.git", from: "1.0.0") ], targets: [ .target(name: "HiyaSkip", dependencies: [ "HiyaSkipModel", .product(name: "SkipFuseUI", package: "skip-fuse-ui") ], resources: [.process("Resources")], plugins: [.plugin(name: "skipstone", package: "skip")]), .target(name: "HiyaSkipModel", dependencies: [ "HiyaSkipLogic", .product(name: "SkipModel", package: "skip-model"), .product(name: "SkipFuse", package: "skip-fuse") ], plugins: [.plugin(name: "skipstone", package: "skip")]), .testTarget(name: "HiyaSkipModelTests", dependencies: [ "HiyaSkipModel", .product(name: "SkipTest", package: "skip") ], plugins: [.plugin(name: "skipstone", package: "skip")]), .target(name: "HiyaSkipLogic", dependencies: []), ] ) ``` -------------------------------- ### SwiftUI Toggle Examples Source: https://skip.dev/docs/components/toggle Demonstrates various ways to initialize and style a SwiftUI Toggle. Includes examples with ViewBuilder init, String init, fixed width, hidden labels, disabled state, foreground style, and tint color. ```swift import SwiftUI struct TogglePlayground: View { @State var isOn = false var body: some View { ScrollView { VStack(spacing: 16.0) { Toggle(isOn: $isOn) { Text("Viewbuilder init") } Toggle("String init", isOn: $isOn) Toggle("Fixed width", isOn: $isOn) .frame(width: 200.0) VStack { Text(".labelsHidden():") Toggle("Label", isOn: $isOn) } .labelsHidden() Toggle(".disabled(true)", isOn: $isOn) .disabled(true) Toggle(".foregroundStyle(.red)", isOn: $isOn) .foregroundStyle(.red) Toggle(".tint(.red)", isOn: $isOn) .tint(.red) } .padding() } .toolbar { PlaygroundSourceLink(file: "TogglePlayground.swift") } } } ``` -------------------------------- ### Manage Swift Android SDK Installation Source: https://skip.dev/docs/skip-cli Installs the Swift Android SDK, which is necessary for compiling Swift code for Android. You can install the latest release, a specific version using `--version`, or the latest nightly build. ```bash # Install the latest release skip android sdk install ``` ```bash # Install a specific version skip android sdk install --version 6.3 ``` ```bash # Install the latest nightly build skip android sdk install --version nightly-main ``` -------------------------------- ### SwiftUI Video Player Example Source: https://skip.dev/docs/components/videoplayer Demonstrates how to create and control a video player in SwiftUI using AVKit. The example includes play/pause functionality and seeking to the beginning of the video. ```swift import AVKit import SwiftUI struct VideoPlayerPlayground: View { @State var player = AVPlayer(playerItem: AVPlayerItem(url: URL(string: "https://skip.tools/assets/introduction.mov")!)) @State var isPlaying: Bool = false var body: some View { VStack { Button { isPlaying ? player.pause() : player.play() isPlaying = !isPlaying player.seek(to: .zero) } label: { Image(systemName: isPlaying ? "stop" : "play") .padding() } VideoPlayer(player: player) } .toolbar { PlaygroundSourceLink(file: "VideoPlayerPlayground.swift") } } } ``` -------------------------------- ### Complete OnSubmit Playground Example Source: https://skip.dev/docs/components/onsubmit This is a complete example of the OnSubmitPlayground struct, demonstrating the use of onSubmit with TextFields and a Form in SwiftUI. ```swift import SwiftUI struct OnSubmitPlayground: View { @State var text1 = "" @State var text2 = "" @State var submitText = "" var body: some View { Form { HStack { Text(submitText) Spacer() Button("Clear") { submitText = "" } } TextField("Text1", text: $text1) .onSubmit { submitText = submitText + "Text1 " } TextField("Text2", text: $text2) .onSubmit { submitText = submitText + "Text2 " } } .onSubmit { submitText = submitText + "Form " } .toolbar { PlaygroundSourceLink(file: "OnSubmitPlayground.swift") } } } ``` -------------------------------- ### Install Swift SDK for Android Source: https://skip.dev/docs/modes Installs the necessary native build tools for the Swift SDK on Android. Run this command before switching a project to Skip Fuse (native mode). ```bash skip android sdk install ``` -------------------------------- ### Launch Android Emulator Source: https://skip.dev/docs/samples/skipapp-fireside Launches a specific Android emulator instance. Ensure Android Studio is installed and an emulator is configured. ```bash $ ~/Library/Android/sdk/emulator/emulator @Pixel_6_API_30 ``` -------------------------------- ### NavigationStack Playground Example Source: https://skip.dev/docs/components/navigationstack This example demonstrates a basic NavigationStack view with a 'Pop' button that dismisses the current view. It includes a toolbar item linking to the source file. ```swift import SwiftUI struct NavigationStackPlayground: View { @Environment(\.dismiss) var dismiss var body: some View { Button("Pop") { dismiss() } .toolbar { PlaygroundSourceLink(file: "NavigationStackPlayground.swift") } } } ``` -------------------------------- ### Embedded WebView Example Source: https://skip.dev/docs/modules/skip-web A basic example demonstrating how to embed a WebView in a Skip Lite app to display a static URL. This requires importing `SkipWeb` and `SwiftUI`. ```swift import Foundation import SwiftUI import SkipWeb struct EmbeddedWebView : View { let url: URL var body: some View { WebView(url: url) } } ``` -------------------------------- ### Create Android Emulator Source: https://skip.dev/docs/gettingstarted Quickly installs and configures an Android emulator for your Skip project. This is essential for local Android app development and testing. ```bash skip android emulator create ``` -------------------------------- ### Show Android Toolchain Version Source: https://skip.dev/docs/skip-cli Display the version of the installed Swift Android Host Toolchain. ```bash skip android toolchain version ``` -------------------------------- ### Determine App Installation Source Source: https://skip.dev/docs/modules/skip-marketplace Get the installation source of the app using `Marketplace.current.installationSource`. This returns an enum indicating where the app was installed from, such as the Apple App Store, Google Play Store, TestFlight, or alternative marketplaces. ```swift switch await Marketplace.current.installationSource { case .appleAppStore: print("Installed from Apple App Store") case .googlePlayStore: print("Installed from Google Play Store") case .testFlight: print("Installed from TestFlight") case .marketplace(let bundleId): print("Installed from EU alternative marketplace: \(bundleId)") case .web: print("Installed via Web Distribution (EU)") case .other(let name): // e.g. "org.fdroid.fdroid" (F-Droid), "com.amazon.venezia" (Amazon Appstore), // "com.rileytestut.AltStore" (AltStore), "com.sec.android.app.samsungapps" (Galaxy Store) print("Installed from: \(name ?? \"unknown\")") case .unknown: print("Installation source unknown (sideload, debug build, or pre-Android 11 missing data)") } ``` -------------------------------- ### Verify Skip Native Environment Source: https://skip.dev/docs/modes Checks your environment for the necessary native build tools. Use this command after installing the Swift SDK for Android. ```bash skip checkup --native ``` -------------------------------- ### Initialize Skip Lottie Demo App Source: https://skip.dev/docs/samples/skipapp-lottiedemo Command to initialize the Skip Lottie Demo app project with specified configurations. ```bash skip init --show-tree --icon-color='1abc9c' --appid=skip.lottie.demo.App --version 0.0.1 skipapp-lottiedemo LottieDemo:skip-motion/SkipMotion:skip-ui/SkipUI ``` -------------------------------- ### Initialize a Multi-Module App Source: https://skip.dev/docs/project-types Use `skip init` with additional module names to create a SwiftPM project with multiple dependent modules. ```bash skip init --native-app --appid=bundle.id.HelloSkip multi-project HelloSkip HelloModel HelloCore ``` -------------------------------- ### Access Firestore Singleton in a Model Actor Source: https://skip.dev/docs/modules/skip-firebase After initializing Firebase, access the `Firestore` singleton to interact with Firestore database services. This example shows how to get the shared instance within an actor. ```swift import SkipFirebaseFirestore ... public actor Model { /// The shared model singleton public static let shared = Model() private let firestore: Firestore private init() { self.firestore = Firestore.firestore() } public func queryData() async throws -> [DataModel] { ... } public func saveData(model: DataModel) async throws { ... } ... } ``` -------------------------------- ### Toolbar Playground Enum and View Source: https://skip.dev/docs/components/toolbar Defines an enum for different toolbar playground types and a main view that lists these types using NavigationLink. This setup allows users to navigate to specific toolbar examples. ```swift import SwiftUI enum ToolbarPlaygroundType: String, CaseIterable { case `default` case tint case custom case label case toolbarItem case toolbarItemGroup case topLeadingItem case topLeadingItemGroup case topLeadingBackButtonHidden case topLeadingTrailingItems case bottom case bottomGroup case bottomSpaced var title: String { switch self { case .default: return "Default" case .tint: return "Tint" case .custom: return "Custom" case .label: return "Label" case .toolbarItem: return "ToolbarItem" case .toolbarItemGroup: return "ToolbarItemGroup" case .topLeadingItem: return ".topLeading" case .topLeadingItemGroup: return ".topLeading Group" case .topLeadingBackButtonHidden: return ".topLeading Back Hidden" case .topLeadingTrailingItems: return "Both Top" case .bottom: return "Bottom" case .bottomGroup: return "Bottom 3 Group" case .bottomSpaced: return "Bottom 3 Spaced" } } } struct ToolbarPlayground: View { var body: some View { List(ToolbarPlaygroundType.allCases, id: \.self) { type in NavigationLink(type.title, value: type) } .toolbar { PlaygroundSourceLink(file: "ToolbarPlayground.swift") } .navigationDestination(for: ToolbarPlaygroundType.self) { switch $0 { case .default: DefaultToolbarItemPlayground() .navigationTitle($0.title) case .tint: TintToolbarItemGroupPlayground() .navigationTitle($0.title) case .custom: CustomToolbarItemPlayground() .navigationTitle($0.title) case .label: LabelToolbarItemPlayground() .navigationTitle($0.title) case .toolbarItem: ToolbarItemPlayground(placement: ToolbarItemPlacement.automatic, placement2: ToolbarItemPlacement.automatic) .navigationTitle($0.title) case .toolbarItemGroup: ToolbarItemGroupPlayground(placement: ToolbarItemPlacement.automatic) .navigationTitle($0.title) case .topLeadingItem: #if os(macOS) // ToolbarItemPlacement.topBarLeading unavailable on macOS #else ToolbarItemPlayground(placement: ToolbarItemPlacement.topBarLeading) .navigationTitle($0.title) #endif case .topLeadingItemGroup: #if os(macOS) // ToolbarItemPlacement.topBarLeading unavailable on macOS #else ToolbarItemGroupPlayground(placement: ToolbarItemPlacement.topBarLeading) .navigationTitle($0.title) #endif case .topLeadingBackButtonHidden: #if os(macOS) // ToolbarItemPlacement.topBarLeading unavailable on macOS #else ToolbarBackButtonHiddenPlayground() .navigationTitle($0.title) #endif case .topLeadingTrailingItems: #if os(macOS) // ToolbarItemPlacement.topBarLeading unavailable on macOS #else ToolbarItemPlayground(placement: ToolbarItemPlacement.topBarLeading, placement2: ToolbarItemPlacement.topBarTrailing) .navigationTitle($0.title) #endif case .bottom: #if os(macOS) // ToolbarItemPlacement.bottomBar unavailable on macOS #else ToolbarItemPlayground(placement: ToolbarItemPlacement.bottomBar, placement2: ToolbarItemPlacement.bottomBar) .navigationTitle($0.title) #endif case .bottomGroup: #if os(macOS) // ToolbarItemPlacement.bottomBar unavailable on macOS #else ToolbarBottomThreePlayground(spaced: false) .navigationTitle($0.title) #endif case .bottomSpaced: #if os(macOS) // ToolbarItemPlacement.bottomBar unavailable on macOS #else ToolbarBottomThreePlayground(spaced: true) .navigationTitle($0.title) #endif } } } } struct DefaultToolbarItemPlayground: View { @Environment(\.dismiss) var dismiss @State var firstTapCount = 0 @State var secondTapCount = 0 ``` -------------------------------- ### SwiftUI Audio Playground with AVAudioRecorder Source: https://skip.dev/docs/modules/skip-av This SwiftUI view allows users to start and stop audio recording, and play back the recording. It includes error handling for playback and conditional logic for Skip-specific Android context setup. ```swift import SwiftUI import AVFoundation struct AudioPlayground: View { @State var isRecording: Bool = false @State var errorMessage: String? = nil @State var audioRecorder: AVAudioRecorder? @State var audioPlayer: AVAudioPlayer? var body: some View { #if SKIP let context = androidx.compose.ui.platform.LocalContext.current #endif return VStack { Button(isRecording ? "Stop Recording" : "Start Recording") { self.isRecording ? self.stopRecording() : self.startRecording() } Button("Play Recording") { try? self.playRecording() } if let errorMessage { Text(errorMessage) .foregroundColor(.red) } } .padding() #if SKIP .onAppear { requestAudioRecordingPermission(context: context) } #endif } var captureURL: URL { get { #if SKIP let context = ProcessInfo.processInfo.androidContext let file = java.io.File(context.filesDir, "recording.m4a") return URL(fileURLWithPath: file.absolutePath) #else return FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask) .first!.appendingPathComponent("recording.m4a") #endif } } func startRecording() { do { #if !SKIP setupAudioSession() #endif self.audioRecorder = try AVAudioRecorder(url: captureURL, settings: [AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVSampleRateKey: 12000, AVNumberOfChannelsKey: 1, AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue]) } catch { print(error.localizedDescription) } audioRecorder?.record() isRecording = true } func stopRecording() { isRecording = false audioRecorder?.stop() } func playRecording() throws { do { guard FileManager.default.fileExists(atPath: captureURL.path) else { errorMessage = "Recording file does not exist." return } audioPlayer = try AVAudioPlayer(contentsOf: captureURL) audioPlayer?.play() errorMessage = "" } catch { logger.error("Could not play audio: \(error.localizedDescription)") errorMessage = "Could not play audio: \(error.localizedDescription)" } } #if SKIP func requestAudioRecordingPermission(context: android.content.Context) { guard let activity = context as? android.app.Activity else { return } // You must also list these permissions in your Manifest.xml let permissions = listOf(android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) androidx.core.app.ActivityCompat.requestPermissions(activity, permissions.toTypedArray(), 1) } #else func setupAudioSession() { let session = AVAudioSession.sharedInstance() do { try session.setCategory(.playAndRecord, mode: .default) try session.setActive(true) } catch { errorMessage = "Failed to setup audio session: \(error.localizedDescription)" } } #endif } ``` -------------------------------- ### Initialize a Dual-Platform Framework Source: https://skip.dev/docs/project-types Use `skip init --native-model` to create a SwiftPM package designed for dual-platform use, bridging Swift to Android's ART Java runtime. ```bash skip init --native-model lib-name ModuleName ``` -------------------------------- ### Install Fastlane with Homebrew Source: https://skip.dev/docs/deployment Install the Fastlane command-line tool using Homebrew. Ensure Homebrew is installed and updated before running this command. ```bash brew install fastlane ``` -------------------------------- ### Sign Up (Register and Login) Source: https://skip.dev/docs/modules/skip-auth0 Creates a new user account and immediately logs the user in, returning authentication tokens. Supports optional parameters like username, connection, scope, and audience for advanced configurations. ```APIDOC ## Sign Up (Register and Login) Creates a new user account and immediately logs in to obtain tokens. ### Method Signature ```swift Auth0SDK.shared.signUp(email: String, password: String, username: String?, connection: String?, scope: String?, audience: String?, completion: @escaping (Result) -> Void) ``` ### Parameters - `email` (String) - The user's email address. - `password` (String) - The user's chosen password. - `username` (String?) - Optional. The username for the user, if required by the connection. - `connection` (String?) - Optional. The name of the Auth0 database connection to use. - `scope` (String?) - Optional. The scopes to request for the tokens (e.g., "openid profile email offline_access"). - `audience` (String?) - Optional. The audience for the access token. ### Request Example ```swift Auth0SDK.shared.signUp(email: "newuser@example.com", password: "securepassword") { result in switch result { case .success(let credentials): print("Signed up and logged in!") print("Access token: \(credentials.accessToken ?? "")") case .failure(let error): print("Sign up failed: \(error)") } } ``` ### Advanced Request Example ```swift Auth0SDK.shared.signUp( email: "newuser@example.com", password: "securepassword", username: "newuser", // If your connection requires usernames connection: "Username-Password-Authentication", scope: "openid profile email offline_access", audience: "https://api.example.com" ) { result in // Handle result... } ``` ### Prerequisites - The “Password” grant type must be enabled in your Auth0 application settings. - The database connection must allow sign-ups (check **Disable Sign Ups** is unchecked in your connection settings). ``` -------------------------------- ### skip android sdk install Source: https://skip.dev/docs/skip-cli Install the Swift Android SDK, which is required for compiling Swift code to run natively on Android. Allows installing the latest release, a specific version, or a nightly build. ```APIDOC ## skip android sdk install ### Description Install the Swift Android SDK. By default, installs the latest released version. ### Usage ``` skip android sdk install [--version ] ``` ### Options * `--version `: Specify the SDK version to install (e.g., `6.3`, `nightly-main`). ### Examples ``` # Install the latest release skip android sdk install # Install a specific version skip android sdk install --version 6.3 # Install the latest nightly build skip android sdk install --version nightly-main ``` ``` -------------------------------- ### List Installed Android Emulators Source: https://skip.dev/docs/skip-cli View a list of all installed Android emulator images (AVDs) on your system. ```bash skip android emulator list ``` -------------------------------- ### Install Skip CLI Source: https://skip.dev/docs/samples/skipapp-fireside Installs the Skip CLI tool using Homebrew. Requires macOS 13+. ```bash $ brew install skiptools/skip/skip ``` -------------------------------- ### Initialize Skip Project Source: https://skip.dev/docs/samples/skipapp-databake Use the skip init command to create a new Skip project. Specify the application ID, icon color, and project name. ```bash skip init --appid=skip.data.bake.App --icon-color=34AADC --free skipapp-databake DataBake DataBakeModel ``` -------------------------------- ### Observable Playground Setup Source: https://skip.dev/docs/components/observable Sets up the main Observable Playground view, conditionally rendering content based on OS version and providing an environment object. ```swift import SwiftUI #if canImport(Observation) import Observation #endif struct ObservablePlayground: View { var body: some View { if #available(iOS 17.0, macOS 14.0, *) { ObservablesOuterView() .environmentObject(PlaygroundEnvironmentObject(text: "initialEnvironment")) .toolbar { PlaygroundSourceLink(file: "ObservablePlayground.swift") } } else { Text("iOS 17 / macOS 14 required for Observation framework") } } } ``` -------------------------------- ### Create a Standard Dual-Platform App with skip init Source: https://skip.dev/docs/project-types Use this command to create a new dual-platform app project. Pass `--native-app` for a Skip Fuse app or `--transpiled-app` for a Skip Lite app. Ensure your `appid` has at least two dot-separated words and that `project-name` and `AppName` are distinct. ```bash skip init --native-app --appid=bundle.id project-name AppName ``` -------------------------------- ### Create and Open a Standard Dual-Platform App in Xcode with skip init Source: https://skip.dev/docs/project-types This command creates a new dual-platform app project and immediately opens it in Xcode. It generates a SwiftPM package with a single module, along with Darwin and Android folders, and a shared Skip.env configuration file. ```bash skip init --open-xcode --native-app --appid=bundle.id.HelloSkip hello-skip HelloSkip ``` -------------------------------- ### Create a Supabase Client Source: https://skip.dev/docs/modules/skip-supabase Initialize the Supabase client with your project's URL and anon key. ```swift import SkipSupabase let client = SupabaseClient( supabaseURL: URL(string: "https://your-project.supabase.co")!, supabaseKey: "your-anon-key" ) ``` -------------------------------- ### TextField OnSubmit Example Source: https://skip.dev/docs/components/onsubmit Use the onSubmit modifier on a TextField to execute code when the user submits the text field, for example, by pressing the return key. ```swift TextField("Text1", text: $text1) .onSubmit { submitText = submitText + "Text1 " } ``` -------------------------------- ### Initialize and Build a Skip Project Source: https://skip.dev/docs/gradle Initializes a new Skip project, resolves dependencies, and builds the project. This sets up the necessary files for Android development. ```bash $ skip init --appid=com.xyz.HelloSkip hello-skip HelloSkip Initializing Skip library hello-skip [✓] Create project hello-skip (0.73s) [✓] Resolve dependencies (5.89s) [✓] Build hello-skip (15.2s) [✓] Created module HelloSkip in ~/Desktop/hello-skip/HelloSkip.xcodeproj $ cd hello-skip $ swift build --build-tests Fetched https://source.skip.tools/skip.git (0.92s) ... [294/294] Linking libHelloSkip.dylib Build complete! (23.13s) ``` -------------------------------- ### Kotlin Wrapper Example with Standard Types Source: https://skip.dev/docs/modes This example shows a generated Kotlin wrapper class using standard Kotlin/Java types, such as `java.net.URI`, when `kotlincompat` option is enabled. ```kotlin package network.utils class URLManager { var urls: kotlin.collections.List get() { // Delegate to native code ... } set(newValue) { // Delegate to native code ... } fun perform(action: (java.net.URI) -> Unit) { // Delegate to native code... } ... } ``` -------------------------------- ### Initialize Skip Project Source: https://skip.dev/docs/project-types Command to initialize a new Skip project with specified configurations, including native app, bridged modules, and module tests. ```bash skip init --native-app --bridged --module-tests --show-tree --appid=ahoy.skipper ahoy-skipper AhoySkipper SkipperModel ``` -------------------------------- ### SwiftUI TextEditor Example Source: https://skip.dev/docs/components/texteditor Demonstrates the basic usage of SwiftUI's TextEditor with a state variable to hold the text content. Includes a toolbar with a source link. ```swift import SwiftUI struct TextEditorPlayground: View { @State var text = """ When in the course of human events, it becomes necessary for an Oppressed People to Rise, and assert their Natural Rights, as Human Beings, as Native & mutual Citizens of a free Republic, and break that odious Yoke of oppression, which is so unjustly laid upon them by their fellow Countrymen, and to assume among the powers of Earth the same equal privileges to which the Laws of Nature, & natures God entitle them; A moderate respect for the opinions of Mankind, requires that they should declare the causes which incite them to this just & worthy action. We hold these truths to be Self Evident; That All Men are Created Equal; That they are endowed by their Creator with certain unalienable rights. That among these are Life, Liberty; & the persuit of happiness. That Nature hath freely given to all Men, a full Supply of Air. Water, & Land; for their sustinance, & mutual happiness, That No Man has any right to deprive his fellow Man, of these Inherent rights, except in punishment of Crime. That to secure these rights governments are instituted among Men, deriving their just powers from the consent of the governed. That when any form of Government, becomes destructive to these ends, It is the right of the People, to alter, Amend, or Remoddel it, Laying its foundation on Such Principles, & organizing its powers in such form as to them shall seem most likely to effect the safety, & happiness of the Human Race. """ var body: some View { TextEditor(text: $text) .toolbar { PlaygroundSourceLink(file: "TextEditorPlayground.swift") } } } ``` -------------------------------- ### Transpiled Kotlin Test Case Example Source: https://skip.dev/docs/modules/skip-unit This is an example of a transpiled Kotlin test case that uses Skip's unit testing framework. It demonstrates how a basic test is structured. ```kotlin package app.module.name import skip.lib.* import skip.unit.* internal class MyUnitTests: XCTestCase { @Test internal fun testSomeLogic() = XCTAssertEqual(1 + 2, 3, "basic test") } ``` -------------------------------- ### SwiftUI Localization Example Source: https://skip.dev/docs/development-topics Localize SwiftUI views by using string interpolation with tokens like '%@' in `xcstrings` catalogs. This example shows a 'Hello Skipper!' message and a tab item. ```swiftui VStack { Text("Hello \(name)!") Image(systemName: "heart.fill") .foregroundStyle(.red) } .font(.largeTitle) .tabItem { Label("Welcome", systemImage: "heart.fill") } ``` -------------------------------- ### Uninstall Android SDKs Source: https://skip.dev/docs/skip-cli Remove installed Android SDKs using `skip android sdk uninstall`. You can uninstall all installed SDKs or specify a particular version with the `--version` flag. ```bash # Uninstall all installed SDKs skip android sdk uninstall ``` ```bash # Uninstall a specific version skip android sdk uninstall --version swift-6.3-RELEASE_android ``` -------------------------------- ### List Installed and Remote Android SDKs Source: https://skip.dev/docs/skip-cli Use `skip android sdk list` to see locally installed SDKs. Add the `--remote` flag to view available SDKs from remote repositories. ```bash # List locally installed SDKs skip android sdk list ``` ```bash # List available remote SDKs skip android sdk list --remote ``` -------------------------------- ### Initialize Skip App Project Source: https://skip.dev/docs/gradle Command to initialize a new Skip Swift app project. Use this to set up a basic project structure with specified application ID and version. ```bash skip init --show-tree --no-build --no-test --no-module-tests --appid=skip.hello.App --version 1.0.0 hello-skip HelloSkip ``` -------------------------------- ### Initialize Hiya Skip Project Source: https://skip.dev/docs/samples/skipapp-hiya Command to initialize a new Skip dual-platform app project with native model and Swift UI. ```bash skip init --native-model --appid=hiya.skip skipapp-hiya HiyaSkip HiyaSkipModel HiyaSkipLogic ``` -------------------------------- ### Check if App is from First-Party Store Source: https://skip.dev/docs/modules/skip-marketplace Use the `isFirstPartyAppStore` property on the installation source to check if the app was installed from the Apple App Store or Google Play Store. This is useful for gating features like in-app reviews. ```swift let source = await Marketplace.current.installationSource if source.isFirstPartyAppStore { Marketplace.current.requestReview() } ``` -------------------------------- ### Initialize SQLContext with SQLPlus Configuration Source: https://skip.dev/docs/modules/skip-sql Import SkipSQLPlus and pass `.plus` to the `SQLContext` constructor to enable its extensions. Ensure the database path is correctly specified. ```swift import SkipSQLCore import SkipSQLPlus let dbpath = URL.applicationSupportDirectory.appendingPathComponent("db.sqlite") let db = try SQLContext(path: dbpath.path, flags: [.create, .readWrite], configuration: .plus) // do something with the database db.close() ``` -------------------------------- ### Initialize Native Skip App Source: https://skip.dev/docs/samples/skipapp-howdy Use this command to initialize a new Skip dual-platform native app project. Specify the --native-app flag for native compilation. ```bash skip init --native-app --appid=skip.howdy.App skipapp-howdy HowdySkip ``` -------------------------------- ### FFI Example: Calling C Functions with SkipFFI Source: https://skip.dev/docs/modules/skip-ffi This example demonstrates how to use SkipFFI to call C standard library functions like `abs`, `malloc`, `free`, and `getenv` from Kotlin, simulating Swift types and using JNA for native access. ```swift #if !SKIP import Darwin #else import SkipFFI let Darwin = BionicDarwin() func BionicDarwin() -> BionicDarwin { com.sun.jna.Native.load("c", (BionicDarwin.self as kotlin.reflect.KClass).java) } protocol BionicDarwin : com.sun.jna.Library { func abs(_ value: Int32) -> Int32 func malloc(_ size: Int32) -> OpaquePointer func free(_ ptr: OpaquePointer) -> Int32 func getenv(_ key: String) -> String? } #endif // Fully-qualified Module.fname() will call through SkipFFI to the C interface Darwin.abs(-12) // 12 Darwin.free(Darwin.malloc(8)) ``` -------------------------------- ### Basic TextField Initialization Source: https://skip.dev/docs/components/textfield Demonstrates the basic initialization of a TextField using a binding to a String and a label. ```swift TextField(text: $text) { Text(".init(text:label:)") } ``` -------------------------------- ### Session Recording Source: https://skip.dev/docs/modules/skip-posthog Methods for starting and stopping session recording. ```APIDOC ## PostHogSDK Session Recording ### Methods #### `startSessionRecording(resumeCurrent:)` - **Description**: Start recording the current user session. - **Parameters**: - `resumeCurrent` (Bool) - Whether to resume recording if it was previously stopped. #### `stopSessionRecording()` - **Description**: Stop recording the current user session. ``` -------------------------------- ### Initialize Skip Lite App Source: https://skip.dev/docs/samples/skipapp-hello Command to initialize a new Skip Lite dual-platform app project with specific configurations. ```bash skip init --zero --appid=skip.hello.App skipapp-hello HelloSkip ``` -------------------------------- ### .zIndex Source: https://skip.dev/docs/modules/skip-ui Sets the z-index of a view for layering. Example usage provided. ```APIDOC ## .zIndex ### Description Controls the drawing layer (z-index) of a view relative to its siblings. ### Method View modifier ### Endpoint N/A (SwiftUI Modifier) ### Parameters - **index**: A CGFloat value determining the stacking order. Higher values are drawn on top. ``` -------------------------------- ### Client Initialization Source: https://skip.dev/docs/modules/skip-supabase Initialize the Supabase client with your project's URL and anon key. ```APIDOC ## Creating a Client ```swift import SkipSupabase let client = SupabaseClient( supabaseURL: URL(string: "https://your-project.supabase.co")!, supabaseKey: "your-anon-key" ) ``` ```