From e6ed8ed98bbf1c5860c9565f5f745e0c6af83ef9 Mon Sep 17 00:00:00 2001 From: nab138 Date: Sat, 20 Sep 2025 17:26:54 -0400 Subject: [PATCH 1/2] Xcode 26 support --- README.md | 6 ++-- src-tauri/src/lsp_utils.rs | 2 +- src-tauri/templates/swiftui/Package.swift | 2 +- src-tauri/templates/uikit/Package.swift | 2 +- src/components/SDKMenu.tsx | 4 +-- src/components/SwiftMenu.tsx | 7 ++-- src/pages/IDE.tsx | 20 ++++++++++-- src/pages/Onboarding.tsx | 28 +++------------- src/utilities/IDEContext.tsx | 40 +++++++++++++++++++---- src/utilities/StoreContext.tsx | 8 ++++- 10 files changed, 75 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 56f2ac4..51c055a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ iOS Swift development IDE for Windows/Linux. Create, build, and test apps without owning a Mac. -Supports Swift 6.1 and the Swift Package Manager. +Supports Swift 6.2 and the Swift Package Manager. ### Demo @@ -30,7 +30,7 @@ Check out the [Getting Started](https://github.com/nab138/CrossCode/wiki#getting ## Features -- Generate a Darwin SDK for linux from a user provided copy of Xcode 16.3 to build the apps +- Generate a Darwin SDK for linux from a user provided copy of Xcode 26 to build the apps - Build apps using swift package manager - Log in with your Apple ID to sign apps - Install apps on device @@ -49,7 +49,7 @@ Please note that I am one person, so development may be slow. If you want to hel ## How it works -- A darwin SDK is generated from a user provided copy of Xcode 16.3 (extracted with [unxip-rs](https://github.com/nab138/unxip-rs)) and darwin tools from [darwin-tools-linux-llvm](https://github.com/xtool-org/darwin-tools-linux-llvm) +- A darwin SDK is generated from a user provided copy of Xcode 26 (extracted with [unxip-rs](https://github.com/nab138/unxip-rs)) and darwin tools from [darwin-tools-linux-llvm](https://github.com/xtool-org/darwin-tools-linux-llvm) - Swift uses the darwin SDK to build an executable which is packaged into an .app bundle. - The code to sign and install apps onto a device has been removed from CrossCode's source and moved to a standalone package, [isideload](https://github.com/nab138/isideload). It was built on a lot of other libraries, so check out its README for more info. diff --git a/src-tauri/src/lsp_utils.rs b/src-tauri/src/lsp_utils.rs index 1e497b0..b05e4bf 100644 --- a/src-tauri/src/lsp_utils.rs +++ b/src-tauri/src/lsp_utils.rs @@ -32,7 +32,7 @@ pub fn validate_project(project_path: String, toolchain_path: String) -> Project // let config_path = project_path.join(".sourcekit-lsp").join("config.json"); // if !config_path.exists() { // fs::write(config_path, "{ -// \"$schema\": \"https://raw.githubusercontent.com/swiftlang/sourcekit-lsp/refs/heads/release/6.1/config.schema.json\", +// \"$schema\": \"https://raw.githubusercontent.com/swiftlang/sourcekit-lsp/refs/heads/release/6.2/config.schema.json\", // \"swiftPM\": { // \"swiftSDK\": \"arm64-apple-ios\" // } diff --git a/src-tauri/templates/swiftui/Package.swift b/src-tauri/templates/swiftui/Package.swift index 6ddc581..82c8f8f 100644 --- a/src-tauri/templates/swiftui/Package.swift +++ b/src-tauri/templates/swiftui/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.1 +// swift-tools-version: 6.2 import PackageDescription diff --git a/src-tauri/templates/uikit/Package.swift b/src-tauri/templates/uikit/Package.swift index 6ddc581..82c8f8f 100644 --- a/src-tauri/templates/uikit/Package.swift +++ b/src-tauri/templates/uikit/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.1 +// swift-tools-version: 6.2 import PackageDescription diff --git a/src/components/SDKMenu.tsx b/src/components/SDKMenu.tsx index 35de414..cb2c14e 100644 --- a/src/components/SDKMenu.tsx +++ b/src/components/SDKMenu.tsx @@ -123,11 +123,11 @@ export default () => { onClick={(e) => { e.preventDefault(); openUrl( - "https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_16.3/Xcode_16.3.xip" + "https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_26/Xcode_26_Universal.xip" ); }} > - Download XCode 16.3 + Download XCode 26 + + + + + )} ); }; diff --git a/src/pages/Onboarding.tsx b/src/pages/Onboarding.tsx index 674ad48..1c298c2 100644 --- a/src/pages/Onboarding.tsx +++ b/src/pages/Onboarding.tsx @@ -1,10 +1,10 @@ -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { open } from "@tauri-apps/plugin-shell"; import "./Onboarding.css"; import { Button, Card, CardContent, Divider, Link, Typography } from "@mui/joy"; import { useIDE } from "../utilities/IDEContext"; import logo from "../assets/logo.png"; -import { useNavigate } from "react-router"; +import { useLocation, useNavigate } from "react-router"; import { openUrl } from "@tauri-apps/plugin-opener"; import SwiftMenu from "../components/SwiftMenu"; import SDKMenu from "../components/SDKMenu"; @@ -14,6 +14,7 @@ import { getVersion } from "@tauri-apps/api/app"; import { invoke } from "@tauri-apps/api/core"; import { useToast } from "react-toast-plus"; import { relaunch } from "@tauri-apps/plugin-process"; +import { SWIFT_VERSION_PREFIX } from "../utilities/constants"; export interface OnboardingProps {} @@ -31,6 +32,18 @@ export default ({}: OnboardingProps) => { fetchVersion(); }, []); + const location = useLocation(); + const darwinSdkRef = useRef(null); + + useEffect(() => { + console.log(location.hash); + if (location.hash === "#install-sdk" && darwinSdkRef.current) { + darwinSdkRef.current.scrollIntoView({ + block: "start", + }); + } + }, [location.hash]); + return (
@@ -230,16 +243,16 @@ export default ({}: OnboardingProps) => { Swift - You will need a Swift 6.2 toolchain to use CrossCode. It is - recommended to install it using swiftly, but you can also install it - manually. + You will need a Swift {SWIFT_VERSION_PREFIX} toolchain to use + CrossCode. It is recommended to install it using swiftly, but you + can also install it manually. - + Darwin SDK CrossCode requires a special swift SDK to build apps for iOS. It can @@ -255,6 +268,7 @@ export default ({}: OnboardingProps) => {
+
); }; diff --git a/src/utilities/IDEContext.tsx b/src/utilities/IDEContext.tsx index acca8f2..7df3d3c 100644 --- a/src/utilities/IDEContext.tsx +++ b/src/utilities/IDEContext.tsx @@ -37,6 +37,7 @@ export interface IDEContextType { isWindows: boolean; hasWSL: boolean; hasDarwinSDK: boolean; + darwinSDKVersion: string; hasLimitedRam: boolean; toolchains: ListToolchainResponse | null; selectedToolchain: Toolchain | null; @@ -100,6 +101,7 @@ export const IDEProvider: React.FC<{ null ); const [hasDarwinSDK, setHasDarwinSDK] = useState(false); + const [darwinSDKVersion, setDarwinSDKVersion] = useState("none"); const [initialized, setInitialized] = useState(false); const [ready, setReady] = useState(null); const [devices, setDevices] = useState([]); @@ -160,13 +162,15 @@ export const IDEProvider: React.FC<{ const checkSDK = useCallback(async () => { try { - let result = await invoke("has_darwin_sdk", { + let result = await invoke("has_darwin_sdk", { toolchainPath: selectedToolchain?.path || "", }); - setHasDarwinSDK(result); + setHasDarwinSDK(result != "none"); + setDarwinSDKVersion(result); } catch (e) { console.error("Failed to check for SDK:", e); setHasDarwinSDK(false); + setDarwinSDKVersion("none"); } }, [selectedToolchain]); @@ -246,7 +250,11 @@ export const IDEProvider: React.FC<{ initialized, ]); + let startedInitializing = useRef(false); + useEffect(() => { + if (startedInitializing.current) return; + startedInitializing.current = true; let initPromises: Promise[] = []; initPromises.push(scanToolchains()); initPromises.push( @@ -260,10 +268,11 @@ export const IDEProvider: React.FC<{ }) ); initPromises.push( - invoke("has_darwin_sdk", { + invoke("has_darwin_sdk", { toolchainPath: selectedToolchain?.path ?? "", }).then((response) => { - setHasDarwinSDK(response as boolean); + setHasDarwinSDK(response != "none"); + setDarwinSDKVersion(response); }) ); initPromises.push( @@ -500,6 +509,7 @@ export const IDEProvider: React.FC<{ setSelectedDevice, mountDdi, ready, + darwinSDKVersion, }), [ isWindows, @@ -522,6 +532,7 @@ export const IDEProvider: React.FC<{ setSelectedDevice, mountDdi, ready, + darwinSDKVersion, ] ); diff --git a/src/utilities/StoreContext.tsx b/src/utilities/StoreContext.tsx index e0114cf..c903b38 100644 --- a/src/utilities/StoreContext.tsx +++ b/src/utilities/StoreContext.tsx @@ -41,13 +41,7 @@ export const StoreProvider: React.FC<{ children: React.ReactNode }> = ({ await setTheme(theme as "light" | "dark"); setMode(theme as "light" | "dark"); - if ((await storeInstance.get("isCrossCodePrefs")) !== true) { - storeInstance.set("isCrossCodePrefs", true); - } else { - if ((await storeInstance.get("lastXcodeVersion")) === undefined) { - storeInstance.set("lastXcodeVersion", "16.3"); - } - } + storeInstance.set("isCrossCodePrefs", true); const keys = await storeInstance.keys(); const values: { [key: string]: any } = {}; diff --git a/src/utilities/constants.ts b/src/utilities/constants.ts new file mode 100644 index 0000000..752e37d --- /dev/null +++ b/src/utilities/constants.ts @@ -0,0 +1,2 @@ +export const SWIFT_VERSION_PREFIX = "6.2"; +export const DARWIN_SDK_VERSION = "26.0";