Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/mobile-sdk-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ on:
branches: [main]
paths:
- 'client/mobile/**'
- '.github/workflows/mobile-sdk-ci.yml'
push:
branches: [main]
paths:
- 'client/mobile/**'
- '.github/workflows/mobile-sdk-ci.yml'

env:
CARGO_TERM_COLOR: always
Expand Down Expand Up @@ -38,3 +40,59 @@ jobs:

- name: Test
run: cargo test

ios-build:
# Compiles the Swift package FOR iOS. `cargo test` (the job above) never
# touches the hand-written Swift wrappers, and a plain `swift build` on
# macOS skips them too — they live under `#if canImport(UIKit)`, which is
# only true when building for an iOS destination. So a Swift API misuse in
# a wrapper (e.g. a wrong UIKit type) was previously invisible until a
# consumer built in Xcode. This job builds the XCFramework (regenerating
# the UniFFI bindings) and compiles the whole package for iOS, catching
# those errors on the PR.
name: iOS Swift Compile
runs-on: macos-15
timeout-minutes: 30

steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable

- name: Add Apple build targets
run: rustup target add aarch64-apple-ios aarch64-apple-ios-sim aarch64-apple-darwin

- uses: Swatinem/rust-cache@v2
with:
workspaces: client/mobile

- name: Build XCFramework (also regenerates UniFFI bindings)
working-directory: client/mobile
run: ./build_xcframework.sh

- name: Point Package.swift at the freshly built XCFramework
run: |
python3 - <<'PY'
import pathlib, re
p = pathlib.Path("Package.swift")
s = p.read_text()
s = re.sub(
r'\.binaryTarget\(\s*name:\s*"rift_ffiFFI".*?\)',
'.binaryTarget(name: "rift_ffiFFI", '
'path: "client/mobile/dist/ios/rift_ffiFFI.xcframework")',
s,
flags=re.S,
)
p.write_text(s)
print(s)
PY

- name: Compile RiftSDK for iOS
# No pipe to `tail` — xcodebuild prints diagnostics inline, and
# truncating the tail hides the actual `error:` lines on failure.
run: |
xcodebuild build \
-scheme RiftSDK \
-destination 'generic/platform=iOS' \
-skipMacroValidation \
CODE_SIGNING_ALLOWED=NO
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PackageDescription
let package = Package(
name: "RiftSDK",
platforms: [
.iOS(.v14), .macOS(.v11)
.iOS(.v15), .macOS(.v11)
],
products: [
.library(name: "RiftSDK", targets: ["RiftSDK"]),
Expand Down
6 changes: 3 additions & 3 deletions client/mobile/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/mobile/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rift_sdk_core"
version = "0.2.2"
version = "0.2.3"
edition = "2021"

[dependencies]
Expand Down
16 changes: 10 additions & 6 deletions client/mobile/dist/ios/Sources/RiftSDK/DeferredDeepLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,21 @@ public extension RiftSdk {
) async throws -> DeferredDeepLinkResult? {
let pasteboard = UIPasteboard.general

// Gate the read. `detectPatterns(for:)` neither exposes the contents
// nor triggers the paste disclosure; it just reports which patterns are
// present. If detection fails, skip rather than read blindly.
let detected: Set<UIPasteboard.DetectedPatterns>
// Gate the read. `detectPatterns(for:)` reports *which* patterns are
// present without exposing the contents, so iOS does NOT surface the
// paste disclosure (unlike `detectValues`, which returns the values and
// does). Only the completion-handler form exists, so bridge it to
// async. If detection fails, skip rather than read blindly.
let detected: Set<PartialKeyPath<UIPasteboard.DetectedValues>>
do {
detected = try await pasteboard.detectPatterns(for: [.probableWebURL])
detected = try await withCheckedThrowingContinuation { continuation in
pasteboard.detectPatterns(for: [\.probableWebURL]) { continuation.resume(with: $0) }
}
} catch {
return nil
}

guard detected.contains(.probableWebURL) else {
guard detected.contains(\UIPasteboard.DetectedValues.probableWebURL) else {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion client/mobile/ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rift_ffi"
version = "0.2.2"
version = "0.2.3"
edition = "2021"

[lib]
Expand Down
2 changes: 1 addition & 1 deletion client/mobile/mobile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rift_mobile"
version = "0.2.2"
version = "0.2.3"
edition = "2021"

[lib]
Expand Down
Loading