Skip to content

Commit 11915fa

Browse files
fix(swift): v0.19.1 - address PR review comments
- Fix VLM pixel format mismatch: RGBX→RGB stripping for macOS NSImage - Fix VLM silent failure: report error when cgImage conversion fails - Fix particle view transparency: set wantsLayer before layer config - Fix toolbar placement: cancellationAction→automatic for nav buttons - Remove tvOS/watchOS from platforms (no binary slices available) - Remove non-deterministic FileManager check from Package.swift - Quote shell command substitutions (SC2046) Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 593e00a commit 11915fa

File tree

6 files changed

+37
-34
lines changed

6 files changed

+37
-34
lines changed

Package.swift

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,8 @@ import Foundation
1818
//
1919
// =============================================================================
2020

21-
// Get the package directory for relative path resolution
22-
let packageDir = URL(fileURLWithPath: #file).deletingLastPathComponent().path
23-
24-
// Path to combined ONNX Runtime xcframework (iOS + macOS)
25-
// Created by: cd sdk/runanywhere-swift && ./scripts/create-onnxruntime-xcframework.sh
26-
let onnxRuntimeLocalPath = "\(packageDir)/sdk/runanywhere-swift/Binaries/onnxruntime.xcframework"
21+
// Combined ONNX Runtime xcframework (local dev) is created by:
22+
// cd sdk/runanywhere-swift && ./scripts/create-onnxruntime-xcframework.sh
2723

2824
// =============================================================================
2925
// BINARY TARGET CONFIGURATION
@@ -45,15 +41,13 @@ let useLocalBinaries = false // Toggle: true for local dev, false for release
4541

4642
// Version for remote XCFrameworks (used when testLocal = false)
4743
// Updated automatically by CI/CD during releases
48-
let sdkVersion = "0.19.0"
44+
let sdkVersion = "0.19.1"
4945

5046
let package = Package(
5147
name: "runanywhere-sdks",
5248
platforms: [
5349
.iOS(.v17),
5450
.macOS(.v14),
55-
.tvOS(.v17),
56-
.watchOS(.v10)
5751
],
5852
products: [
5953
// =================================================================
@@ -219,24 +213,14 @@ func binaryTargets() -> [Target] {
219213
),
220214
]
221215

222-
// Use local combined ONNX Runtime xcframework if available (includes macOS),
223-
// otherwise fall back to iOS-only pod archive from onnxruntime.ai
224-
if FileManager.default.fileExists(atPath: onnxRuntimeLocalPath) {
225-
targets.append(
226-
.binaryTarget(
227-
name: "ONNXRuntimeBinary",
228-
path: "sdk/runanywhere-swift/Binaries/onnxruntime.xcframework"
229-
)
230-
)
231-
} else {
232-
targets.append(
233-
.binaryTarget(
234-
name: "ONNXRuntimeBinary",
235-
url: "https://download.onnxruntime.ai/pod-archive-onnxruntime-c-1.17.1.zip",
236-
checksum: "9a2d54d4f503fbb82d2f86361a1d22d4fe015e2b5e9fb419767209cc9ab6372c"
237-
)
216+
// Local combined ONNX Runtime xcframework (iOS + macOS)
217+
// Created by: cd sdk/runanywhere-swift && ./scripts/create-onnxruntime-xcframework.sh
218+
targets.append(
219+
.binaryTarget(
220+
name: "ONNXRuntimeBinary",
221+
path: "sdk/runanywhere-swift/Binaries/onnxruntime.xcframework"
238222
)
239-
}
223+
)
240224

241225
return targets
242226
} else {

examples/ios/RunAnywhereAI/RunAnywhereAI/Features/Chat/Views/ChatInterfaceView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ extension ChatInterfaceView {
140140
modelButton
141141
}
142142
#else
143-
ToolbarItem(placement: .cancellationAction) {
143+
ToolbarItem(placement: .automatic) {
144144
Button {
145145
showingConversationList = true
146146
} label: {

examples/ios/RunAnywhereAI/RunAnywhereAI/Features/Vision/VLMViewModel.swift

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,25 +192,43 @@ final class VLMViewModel: NSObject {
192192

193193
do {
194194
guard let cgImage = nsImage.cgImage(forProposedRect: nil, context: nil, hints: nil) else {
195+
let conversionError = NSError(
196+
domain: "com.runanywhere.RunAnywhereAI",
197+
code: -1,
198+
userInfo: [NSLocalizedDescriptionKey: "Failed to convert NSImage to CGImage"]
199+
)
200+
self.error = conversionError
201+
logger.error("VLM error: failed to convert NSImage to CGImage")
195202
isProcessing = false
196203
return
197204
}
198205
let width = cgImage.width
199206
let height = cgImage.height
200-
let bytesPerRow = 4 * width
201-
var rgbData = Data(count: bytesPerRow * height)
202-
rgbData.withUnsafeMutableBytes { ptr in
207+
let rgbaBytesPerRow = 4 * width
208+
let rgbaTotalBytes = rgbaBytesPerRow * height
209+
var rgbaData = Data(count: rgbaTotalBytes)
210+
rgbaData.withUnsafeMutableBytes { ptr in
203211
guard let context = CGContext(
204212
data: ptr.baseAddress,
205213
width: width,
206214
height: height,
207215
bitsPerComponent: 8,
208-
bytesPerRow: bytesPerRow,
216+
bytesPerRow: rgbaBytesPerRow,
209217
space: CGColorSpaceCreateDeviceRGB(),
210218
bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue
211219
) else { return }
212220
context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
213221
}
222+
// RGBX (4 bytes/pixel) → RGB (3 bytes/pixel): strip the padding byte
223+
var rgbData = Data(capacity: width * height * 3)
224+
rgbaData.withUnsafeBytes { buffer in
225+
let pixels = buffer.bindMemory(to: UInt8.self)
226+
for i in stride(from: 0, to: rgbaTotalBytes, by: 4) {
227+
rgbData.append(pixels[i]) // R
228+
rgbData.append(pixels[i + 1]) // G
229+
rgbData.append(pixels[i + 2]) // B
230+
}
231+
}
214232
let image = VLMImage(rgbPixels: rgbData, width: width, height: height)
215233
let result = try await RunAnywhere.processImageStream(
216234
image,

examples/ios/RunAnywhereAI/RunAnywhereAI/Features/Voice/VoiceAssistantParticleView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ struct VoiceAssistantParticleView: NSViewRepresentable {
404404
view.preferredFramesPerSecond = 60
405405
view.isPaused = false
406406
view.enableSetNeedsDisplay = false
407+
view.wantsLayer = true
407408
view.layer?.isOpaque = false
408409

409410
if let device = view.device {

sdk/runanywhere-commons/scripts/build-ios.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ build_macos() {
213213
-DRAC_BUILD_JNI=OFF \
214214
$BACKEND_FLAGS
215215

216-
cmake --build . --config "${BUILD_TYPE}" -j$(sysctl -n hw.ncpu)
216+
cmake --build . --config "${BUILD_TYPE}" -j"$(sysctl -n hw.ncpu)"
217217

218218
cd "${PROJECT_ROOT}"
219219
log_info "Built macOS arm64"
@@ -261,7 +261,7 @@ build_platform() {
261261
-DRAC_BUILD_JNI=OFF \
262262
$BACKEND_FLAGS
263263

264-
cmake --build . --config "${BUILD_TYPE}" -j$(sysctl -n hw.ncpu)
264+
cmake --build . --config "${BUILD_TYPE}" -j"$(sysctl -n hw.ncpu)"
265265

266266
cd "${PROJECT_ROOT}"
267267
log_info "Built ${PLATFORM}"

sdk/runanywhere-commons/scripts/macos/download-sherpa-onnx.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ cmake "${BUILD_TEMP}/sherpa-onnx" \
8686
-DSHERPA_ONNX_ENABLE_WEBSOCKET=OFF \
8787
-DSHERPA_ONNX_ENABLE_GPU=OFF
8888

89-
cmake --build . --config Release -j$(sysctl -n hw.ncpu)
89+
cmake --build . --config Release -j"$(sysctl -n hw.ncpu)"
9090

9191
# Collect static libraries and headers
9292
echo ""

0 commit comments

Comments
 (0)