Skip to content

Comments

Mac changes (Changes needed to enable MacOS for distribution)#405

Merged
shubhammalhotra28 merged 2 commits intomainfrom
mac-changes
Feb 21, 2026
Merged

Mac changes (Changes needed to enable MacOS for distribution)#405
shubhammalhotra28 merged 2 commits intomainfrom
mac-changes

Conversation

@shubhammalhotra28
Copy link
Contributor

@shubhammalhotra28 shubhammalhotra28 commented Feb 21, 2026

Changes needed to enable MacOS for distribution


Important

Enable MacOS support for distribution by updating package dependencies, Xcode project settings, and handling audio input in AudioCaptureManager.swift.

  • Package Configuration:
    • Set useLocalBinaries to true in Package.swift for local development.
    • Add dependencies RACommonsBinary, RABackendONNXBinary, ONNXRuntimeBinary, and RABackendLlamaCPPBinary in Package.swift.
  • Xcode Project:
    • Set ARCHS to arm64 in project.pbxproj for Debug and Release configurations.
    • Add OTHER_LDFLAGS = "-all_load" and INFOPLIST_KEY_LSApplicationCategoryType in project.pbxproj.
  • Audio Capture:
    • In AudioCaptureManager.swift, handle MacOS audio input by preparing AVAudioEngine and checking inputFormat validity.
    • Add AudioCaptureError.noInputDevice to handle cases with no valid audio input device.

This description was created by Ellipsis for 30ec6d1. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • New Features

    • Added audio input device detection and comprehensive validation for improved device compatibility
  • Bug Fixes

    • Enhanced audio capture handling on macOS systems with improved initialization workflow
    • Improved error reporting with clearer messages when audio input devices are unavailable
  • Chores

    • Updated build configurations for ARM 64-bit architecture support
    • Migrated to local binary frameworks for development workflows

Greptile Summary

This PR adds MacOS support to the Swift SDK, including proper audio input handling and Xcode project configuration. However, it introduces critical issues in Package.swift that will break SPM distribution for external consumers.

Major changes:

  • Added MacOS audio input support in AudioCaptureManager.swift with proper AVAudioEngine.prepare() call and input device validation
  • Configured Xcode project for MacOS distribution with arm64 architecture, app category type, and -all_load linker flag
  • Critical Issue: Set useLocalBinaries = true in Package.swift, which breaks SPM distribution (was intentionally set to false in commit 4d34930)
  • Critical Issue: Added duplicate binary dependencies to runtime targets (RunAnywhere, ONNXRuntime, LlamaCPPRuntime) that are already dependencies of their respective header targets

The AudioCaptureManager.swift changes are excellent - they properly handle MacOS's lack of AVAudioSession by calling engine.prepare() before reading input format, and add proper error handling for missing audio input devices. The converter.reset() call is also a good fix for MacOS-specific converter state issues.

The Xcode project changes are appropriate for MacOS distribution, though restricting to arm64 only will exclude Intel Macs.

The Package.swift changes must be reverted before merging - the useLocalBinaries toggle should remain false for distribution, and the duplicate binary dependencies will cause linking issues.

Confidence Score: 1/5

  • This PR has critical issues in Package.swift that will break SPM distribution for external consumers
  • The useLocalBinaries = true change and duplicate binary dependencies in Package.swift will break the SDK for all external consumers using Swift Package Manager. While the AudioCaptureManager.swift changes are excellent, the Package.swift issues make this unsafe to merge as-is
  • Package.swift requires immediate attention - revert useLocalBinaries to false and remove duplicate binary dependencies before merging

Important Files Changed

Filename Overview
Package.swift Toggles useLocalBinaries to true and adds binary dependencies to runtime targets - breaks SPM distribution for external consumers
examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj Sets architecture to arm64, adds app category type, and includes -all_load linker flag for MacOS distribution
sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift Adds MacOS audio input support with proper AVAudioEngine initialization and error handling for missing input devices

Last reviewed commit: 30ec6d1

@shubhammalhotra28
Copy link
Contributor Author

@coderabbitai please do a review

Copy link

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 30ec6d1 in 11 seconds. Click for details.
  • Reviewed 200 lines of code in 3 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.

Workflow ID: wflow_t2MMcq5yWWurkn55

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@shubhammalhotra28
Copy link
Contributor Author

@greptile please do a review

@coderabbitai
Copy link

coderabbitai bot commented Feb 21, 2026

📝 Walkthrough

Walkthrough

The PR switches the Swift package from remote-binary usage to local XCFrameworks by default, updates iOS project build architecture and linking configurations, and improves macOS audio capture reliability through new error handling and device validation logic.

Changes

Cohort / File(s) Summary
Binary Configuration
Package.swift
Toggles useLocalBinaries from false to true and adds dependencies on RACommonsBinary, RABackendONNXBinary, RABackendLlamaCPPBinary, and ONNXRuntimeBinary across RunAnywhere, ONNXRuntime, and LlamaCPPRuntime targets. Declares corresponding local binary targets in development mode.
Build Settings
examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj
Sets ARCHS to arm64, adds LSApplicationCategoryType entries to XCBuildConfiguration blocks, and applies -all_load to OTHER_LDFLAGS in Release configurations.
Audio Capture Improvements
sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift
Introduces noInputDevice error case to AudioCaptureError, adds macOS-specific engine preparation before format reading, validates input format properties (sampleRate and channelCount), and resets AVAudioConverter at the start of each conversion to prevent state issues.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #294: Modifies Package.swift to toggle useLocalBinaries flag and update binary target declarations between local and remote modes.
  • PR #323: Adjusts Package.swift binary-target configuration including the useLocalBinaries toggle and binary target declarations with checksum handling.

Poem

🐰 Local frameworks now take the lead,
iOS arm64 gets what it needs,
On macOS, audio flows with care,
No missing devices, just clean air! 🎵

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete and missing critical required sections from the template, including Type of Change, Testing checklist, Platform-Specific Testing, and Labels. Complete the PR description by filling out all required template sections: select Type of Change, mark Testing checkboxes (especially Platform-Specific Testing for Mac), add appropriate Labels (Swift SDK and iOS Sample), and include a Checklist confirmation.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main purpose of the changeset—enabling macOS support for distribution with necessary configuration updates.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mac-changes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link

coderabbitai bot commented Feb 21, 2026

@shubhammalhotra28, I'll review the changes in this PR right away.


🧠 Learnings used
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: sdk/runanywhere-commons/CLAUDE.md:0-0
Timestamp: 2026-01-16T07:01:03.349Z
Learning: iOS/macOS outputs must be packaged as XCFramework format for each library (RACommons, RABackendLLAMACPP, RABackendONNX)
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

//
// =============================================================================
let useLocalBinaries = false // Toggle: true for local dev, false for release
let useLocalBinaries = true // Toggle: true for local dev, false for release
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting useLocalBinaries = true breaks SPM distribution for external consumers. This was intentionally set to false in commit 4d34930. If this change is for local development only, it should not be committed to the main branch.

Suggested change
let useLocalBinaries = true // Toggle: true for local dev, false for release
let useLocalBinaries = false // Toggle: true for local dev, false for release
Prompt To Fix With AI
This is a comment left during a code review.
Path: Package.swift
Line: 40

Comment:
Setting `useLocalBinaries = true` breaks SPM distribution for external consumers. This was intentionally set to `false` in commit 4d349301. If this change is for local development only, it should not be committed to the main branch.

```suggestion
let useLocalBinaries = false //  Toggle: true for local dev, false for release
```

How can I resolve this? If you propose a fix, please make it concise.

.product(name: "Sentry", package: "sentry-cocoa"),
.product(name: "StableDiffusion", package: "ml-stable-diffusion"),
"CRACommons",
"RACommonsBinary",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RACommonsBinary is already added as a dependency to the CRACommons target (line 94). Adding it again to the RunAnywhere target creates a duplicate dependency that may cause linking issues.

Suggested change
"RACommonsBinary",
"CRACommons",
Prompt To Fix With AI
This is a comment left during a code review.
Path: Package.swift
Line: 134

Comment:
`RACommonsBinary` is already added as a dependency to the `CRACommons` target (line 94). Adding it again to the `RunAnywhere` target creates a duplicate dependency that may cause linking issues.

```suggestion
                "CRACommons",
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +154 to +155
"RABackendONNXBinary",
"ONNXRuntimeBinary",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RABackendONNXBinary and ONNXRuntimeBinary are already added as dependencies to the ONNXBackend target (line 114). Adding them again to the ONNXRuntime target creates duplicate dependencies.

Suggested change
"RABackendONNXBinary",
"ONNXRuntimeBinary",
"ONNXBackend",
Prompt To Fix With AI
This is a comment left during a code review.
Path: Package.swift
Line: 154-155

Comment:
`RABackendONNXBinary` and `ONNXRuntimeBinary` are already added as dependencies to the `ONNXBackend` target (line 114). Adding them again to the `ONNXRuntime` target creates duplicate dependencies.

```suggestion
                "ONNXBackend",
```

How can I resolve this? If you propose a fix, please make it concise.

dependencies: [
"RunAnywhere",
"LlamaCPPBackend",
"RABackendLlamaCPPBinary",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RABackendLlamaCPPBinary is already added as a dependency to the LlamaCPPBackend target (line 104). Adding it again to the LlamaCPPRuntime target creates a duplicate dependency.

Suggested change
"RABackendLlamaCPPBinary",
"LlamaCPPBackend",
Prompt To Fix With AI
This is a comment left during a code review.
Path: Package.swift
Line: 176

Comment:
`RABackendLlamaCPPBinary` is already added as a dependency to the `LlamaCPPBackend` target (line 104). Adding it again to the `LlamaCPPRuntime` target creates a duplicate dependency.

```suggestion
                "LlamaCPPBackend",
```

How can I resolve this? If you propose a fix, please make it concise.

isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = arm64;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restricting to arm64 only excludes Intel Macs - consider using ARCHS = "$(ARCHS_STANDARD)" to support both Apple Silicon and Intel Macs unless there's a specific reason to exclude Intel

Prompt To Fix With AI
This is a comment left during a code review.
Path: examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj
Line: 415

Comment:
Restricting to `arm64` only excludes Intel Macs - consider using `ARCHS = "$(ARCHS_STANDARD)"` to support both Apple Silicon and Intel Macs unless there's a specific reason to exclude Intel

How can I resolve this? If you propose a fix, please make it concise.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Package.swift (1)

130-144: ⚠️ Potential issue | 🟡 Minor

RACommonsBinary, ONNXRuntimeBinary, and RABackendLlamaCPPBinary are transitive dependencies—direct listings are redundant.

  • CRACommons declares ["RACommonsBinary"] as its dependency; RunAnywhere does not need to list it again.
  • ONNXBackend declares ["RABackendONNXBinary", "ONNXRuntimeBinary"]; ONNXRuntime should not duplicate these.
  • LlamaCPPBackend declares ["RABackendLlamaCPPBinary"]; LlamaCPPRuntime should not duplicate it.

SPM properly propagates binary target linkage through intermediate targets. These direct references add noise and create unnecessary coupling. Remove them unless there is a specific workaround reason that should be documented in a code comment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Package.swift` around lines 130 - 144, The Package.swift currently lists
transitive binary targets directly—remove the redundant direct references to
RACommonsBinary from the RunAnywhere target, ONNXRuntimeBinary (and
RABackendONNXBinary if duplicated) from the ONNXRuntime target, and
RABackendLlamaCPPBinary from the LlamaCPPRuntime target so those binaries are
only declared by their intermediate targets (CRACommons, ONNXBackend,
LlamaCPPBackend) and SPM can propagate linkage; update the targets' dependency
arrays (e.g., the RunAnywhere target, ONNXRuntime target, and LlamaCPPRuntime
target) to drop those binary names and, if you believe a workaround is required,
leave a short in-code comment explaining why the transitive declaration must be
bypassed.
🧹 Nitpick comments (2)
sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift (2)

188-192: converter.reset() is applied unconditionally — comment could clarify this is intentional.

The reset is called on all platforms, but the comment only mentions macOS. This is actually a good approach (safe no-op elsewhere, prevents future surprises), but a one-word tweak to the comment would reduce confusion for future readers.

✏️ Suggested comment tweak
-        // The input block returns .endOfStream after providing one buffer.
-        // On macOS the converter stays in that "finished" state across calls,
-        // producing empty output for every subsequent buffer. Resetting before
-        // each conversion clears the state so the next buffer is processed.
+        // The input block returns .endOfStream after providing one buffer.
+        // On macOS the converter stays in that "finished" state across calls,
+        // producing empty output for every subsequent buffer. Resetting before
+        // each conversion clears the state so the next buffer is processed
+        // correctly. This is a no-op on platforms unaffected by the issue.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift`
around lines 188 - 192, Update the comment above converter.reset() in
AudioCaptureManager.swift to state that the reset is intentionally applied on
all platforms (it's required on macOS to clear the converter's finished state
and is a safe no-op on others), so future readers understand this is deliberate;
reference the converter.reset() call and the surrounding conversion logic in the
AudioCaptureManager class when editing the comment.

32-32: Consider adopting @MainActor isolation for Swift 6 strict concurrency.

AudioCaptureManager publishes @Published properties and mutates them via DispatchQueue.main.async. Under Swift 6 strict concurrency checking, this class would benefit from @MainActor isolation, which would make the main-actor requirement compile-time enforced rather than convention-based. This isn't urgent for this PR but worth noting given the guideline. As per coding guidelines: "Use the latest Swift 6 APIs always".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift`
at line 32, AudioCaptureManager currently updates `@Published` properties via
DispatchQueue.main.async which is fragile under Swift 6 strict concurrency;
annotate the class with `@MainActor` to give it main-actor isolation so property
publishes and mutations are compile-time enforced, then remove or simplify
explicit DispatchQueue.main.async calls inside methods that mutate the
`@Published` properties (or mark any intentionally off-main methods as nonisolated
if needed), referencing the AudioCaptureManager class and its `@Published`
properties to locate where to apply the annotation and adjust async dispatches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj`:
- Line 544: The Release build config sets OTHER_LDFLAGS = "-all_load" which both
omits $(inherited) and is missing from the Debug config; update the Release
entry for OTHER_LDFLAGS to include inherited flags (e.g. OTHER_LDFLAGS =
"$(inherited) -all_load";) and add the same OTHER_LDFLAGS = "$(inherited)
-all_load"; line to the Debug target config (the config block identified by
5480A2132E2F250400337F2F) so Debug/Release are consistent and
project-level/xcconfig flags are preserved.

In `@Package.swift`:
- Line 40: The package currently sets useLocalBinaries = true which causes
binaryTargets() to emit path-based .binaryTarget entries that break external SPM
consumers; change useLocalBinaries to false and update binaryTargets() to return
the released .binaryTarget entries (URL + checksum) used for published releases
instead of local path-based targets (refer to the useLocalBinaries flag and
binaryTargets() function in Package.swift), and ensure this flag is false (and
the remote .binaryTarget values present) before creating a release tag.

---

Outside diff comments:
In `@Package.swift`:
- Around line 130-144: The Package.swift currently lists transitive binary
targets directly—remove the redundant direct references to RACommonsBinary from
the RunAnywhere target, ONNXRuntimeBinary (and RABackendONNXBinary if
duplicated) from the ONNXRuntime target, and RABackendLlamaCPPBinary from the
LlamaCPPRuntime target so those binaries are only declared by their intermediate
targets (CRACommons, ONNXBackend, LlamaCPPBackend) and SPM can propagate
linkage; update the targets' dependency arrays (e.g., the RunAnywhere target,
ONNXRuntime target, and LlamaCPPRuntime target) to drop those binary names and,
if you believe a workaround is required, leave a short in-code comment
explaining why the transitive declaration must be bypassed.

---

Nitpick comments:
In
`@sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift`:
- Around line 188-192: Update the comment above converter.reset() in
AudioCaptureManager.swift to state that the reset is intentionally applied on
all platforms (it's required on macOS to clear the converter's finished state
and is a safe no-op on others), so future readers understand this is deliberate;
reference the converter.reset() call and the surrounding conversion logic in the
AudioCaptureManager class when editing the comment.
- Line 32: AudioCaptureManager currently updates `@Published` properties via
DispatchQueue.main.async which is fragile under Swift 6 strict concurrency;
annotate the class with `@MainActor` to give it main-actor isolation so property
publishes and mutations are compile-time enforced, then remove or simplify
explicit DispatchQueue.main.async calls inside methods that mutate the
`@Published` properties (or mark any intentionally off-main methods as nonisolated
if needed), referencing the AudioCaptureManager class and its `@Published`
properties to locate where to apply the annotation and adjust async dispatches.

"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 15.5;
MARKETING_VERSION = 0.17.2;
OTHER_LDFLAGS = "-all_load";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

-all_load is Release-only and is missing $(inherited) — both can cause hidden issues.

Two concerns:

  1. Debug/Release asymmetry: OTHER_LDFLAGS = "-all_load" is present only in the Release target config but absent from the Debug config (line 469 block). Duplicate-symbol linker errors caused by -all_load will surface only in Release, making them much harder to reproduce and debug. Likewise, code paths reachable only because -all_load forces extra object files into the binary will silently be absent in Debug builds.

  2. Missing $(inherited): The bare string value overwrites any OTHER_LDFLAGS injected by xcconfig files or the project level. Adding $(inherited) preserves those flags.

🔧 Suggested fix
-				OTHER_LDFLAGS = "-all_load";
+				OTHER_LDFLAGS = (
+					"-all_load",
+					"$(inherited)",
+				);

And add the matching entry to the Debug target config (5480A2132E2F250400337F2F, around line 480):

+				OTHER_LDFLAGS = (
+					"-all_load",
+					"$(inherited)",
+				);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj` at line
544, The Release build config sets OTHER_LDFLAGS = "-all_load" which both omits
$(inherited) and is missing from the Debug config; update the Release entry for
OTHER_LDFLAGS to include inherited flags (e.g. OTHER_LDFLAGS = "$(inherited)
-all_load";) and add the same OTHER_LDFLAGS = "$(inherited) -all_load"; line to
the Debug target config (the config block identified by
5480A2132E2F250400337F2F) so Debug/Release are consistent and
project-level/xcconfig flags are preserved.

//
// =============================================================================
let useLocalBinaries = false // Toggle: true for local dev, false for release
let useLocalBinaries = true // Toggle: true for local dev, false for release
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

useLocalBinaries = true will break all external SPM consumers when this is merged.

The in-file comment explicitly documents the intent:

  • truelocal development only (requires sdk/runanywhere-swift/Binaries/ to be present locally)
  • falseexternal users via SPM; no setup needed

When SPM resolves a package dependency, it clones the whole repository, performs a checkout on the specified ref, and searches for the binary artifact there. With useLocalBinaries = true, the binaryTargets() function returns path-based targets like:

.binaryTarget(name: "RACommonsBinary",
              path: "sdk/runanywhere-swift/Binaries/RACommons.xcframework")

Those Binaries/ directories are generated by the local setup script and are not committed to the repository. Any consumer who adds the package via:

.package(url: "https://github.com/RunanywhereAI/runanywhere-sdks", from: "0.17.0")

…will immediately fail package resolution with "target path not found" on the missing XCFramework directories.

This flag must be reset to false before the release tag is cut.

🔧 Fix
-let useLocalBinaries = true //  Toggle: true for local dev, false for release
+let useLocalBinaries = false //  Toggle: true for local dev, false for release
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Package.swift` at line 40, The package currently sets useLocalBinaries = true
which causes binaryTargets() to emit path-based .binaryTarget entries that break
external SPM consumers; change useLocalBinaries to false and update
binaryTargets() to return the released .binaryTarget entries (URL + checksum)
used for published releases instead of local path-based targets (refer to the
useLocalBinaries flag and binaryTargets() function in Package.swift), and ensure
this flag is false (and the remote .binaryTarget values present) before creating
a release tag.

@coderabbitai
Copy link

coderabbitai bot commented Feb 21, 2026

📝 Walkthrough

Walkthrough

This PR switches the Swift package to use local XCFrameworks for development by toggling the useLocalBinaries flag and adding binary target declarations. It updates iOS build configurations to specify arm64 architecture and add utility app category designation. The PR also enhances audio capture error handling with input device validation and macOS-specific AVAudioConverter management.

Changes

Cohort / File(s) Summary
Binary Target Configuration
Package.swift
Toggled useLocalBinaries flag to true; added local and production binary target declarations for RACommonsBinary, RABackendLlamaCPPBinary, RABackendONNXBinary, and ONNXRuntimeBinary; updated RunAnywhere, ONNXRuntime, and LlamaCPPRuntime target dependencies to include respective binaries.
Build Configuration
examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj
Added arm64 architecture restriction via ARCHS setting across Debug/Release configurations; introduced INFOPLIST_KEY_LSApplicationCategoryType set to "public.app-category.utilities"; added OTHER_LDFLAGS with "-all_load" in Release configurations for RunAnywhere target.
Audio Input Validation
sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift
Added input device presence validation checking sampleRate and channelCount; introduced macOS-specific engine.prepare() call before reading input format; added AVAudioConverter reset before each conversion; introduced new public error case noInputDevice with corresponding error description.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

ios-sdk

Suggested reviewers

  • Siddhesh2377

Poem

🐰 Binaries bundled local, no network delay,
Audio capture now checks—"device, are you there, I say?"
Arm64 marches on, utilities declared,
Converters reset fresh, macOS woes repaired!
With frameworks in hand, development flies!

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Mac changes (Changes needed to enable MacOS for distribution)' is vague and generic, using unclear phrasing that doesn't specifically convey what the changes accomplish beyond mentioning macOS. Use a more specific title that clearly describes the primary change, such as 'Add macOS support with audio input handling and binary dependencies' or 'Enable macOS distribution for Swift SDK'.
Linked Issues check ❓ Inconclusive The PR description does not reference any linked issues or GitHub issue numbers that would track the macOS support work or explain the rationale for the specific Package.swift configuration changes. Link relevant GitHub issues that document the macOS support requirements and clarify why useLocalBinaries must be true for this change.
Out of Scope Changes check ❓ Inconclusive The project.pbxproj changes adding ARCHS=arm64 restrict builds to arm64 only, excluding Intel Mac support, which may be an unintended scope limitation not discussed in the description. Clarify whether arm64-only restriction is intentional or if both arm64 and x86_64 architectures should be supported for broader macOS compatibility.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description includes most required sections (Type of Change, Testing, Platform-Specific Testing, Labels, Checklist) but many checkboxes remain unchecked, indicating incomplete testing verification and label assignment.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mac-changes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj (1)

411-415: ⚠️ Potential issue | 🟡 Minor

ARCHS = arm64 is set at the project level only for Release, not Debug.

The project-level Release config (line 415) adds ARCHS = arm64, but the project-level Debug config (lines 348–410) does not. While the target-level configs both specify ARCHS = arm64 (lines 469, 514), the project-level asymmetry is unexpected. If any target doesn't override ARCHS, it will behave differently between Debug and Release.

For consistency, add ARCHS = arm64 to the project-level Debug config as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj` around
lines 411 - 415, Project-level Debug XCBuildConfiguration is missing the ARCHS =
arm64 setting that the Release configuration has; update the project-level Debug
buildSettings (the XCBuildConfiguration block for Debug) to include ARCHS =
arm64 so Debug and Release are symmetric with the project-level buildSettings
and match the target-level ARCHS overrides (the target XCBuildConfiguration
blocks that currently specify ARCHS = arm64).
🧹 Nitpick comments (1)
sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift (1)

80-80: Consider @Sendable annotation for the closure parameter.

onAudioData is invoked from the audio engine's tap callback (background thread) and dispatched to main. Under Swift 6 strict concurrency checking, an @escaping closure crossing isolation boundaries without @Sendable will produce warnings/errors. Since the coding guideline requires the latest Swift 6 APIs, marking this @Sendable would future-proof the API.

-    public func startRecording(onAudioData: `@escaping` (Data) -> Void) throws {
+    public func startRecording(onAudioData: `@escaping` `@Sendable` (Data) -> Void) throws {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift`
at line 80, The startRecording API accepts an escaping closure that will be
invoked from an audio engine callback on background threads; update the
declaration of public func startRecording(onAudioData: `@escaping` (Data) -> Void)
throws to require a `@Sendable` closure (i.e., onAudioData: `@Sendable` `@escaping`
(Data) -> Void) so it is safe to cross concurrency boundaries under Swift 6;
update any internal call sites or stored properties that capture the closure to
preserve the `@Sendable` signature and adjust call-site captures if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj`:
- Around line 411-415: Project-level Debug XCBuildConfiguration is missing the
ARCHS = arm64 setting that the Release configuration has; update the
project-level Debug buildSettings (the XCBuildConfiguration block for Debug) to
include ARCHS = arm64 so Debug and Release are symmetric with the project-level
buildSettings and match the target-level ARCHS overrides (the target
XCBuildConfiguration blocks that currently specify ARCHS = arm64).

---

Duplicate comments:
In `@examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj`:
- Line 544: The Release build config currently sets OTHER_LDFLAGS = "-all_load"
which both overwrites inherited flags and introduces Release-only linker
behavior; update the Release configuration to prepend $(inherited) and include
-all_load as needed (e.g., OTHER_LDFLAGS = $(inherited) "-all_load") and ensure
Debug does NOT include "-all_load" (or explicitly uses $(inherited) without
-all_load) so inherited xcconfig/project flags are preserved and -all_load
remains Release-only; locate the OTHER_LDFLAGS entry in the project.pbxproj for
the Release configuration to apply this change.

In `@Package.swift`:
- Line 40: The package-level toggle useLocalBinaries in Package.swift is
currently true and must be set to false before merging because local Binaries/
paths break SPM resolution for external consumers; update the literal assignment
of useLocalBinaries to false in Package.swift (and verify there are no other
occurrences of this flag left true) so the package references the
remote/packaged binaries instead of local paths.

---

Nitpick comments:
In
`@sdk/runanywhere-swift/Sources/RunAnywhere/Features/STT/Services/AudioCaptureManager.swift`:
- Line 80: The startRecording API accepts an escaping closure that will be
invoked from an audio engine callback on background threads; update the
declaration of public func startRecording(onAudioData: `@escaping` (Data) -> Void)
throws to require a `@Sendable` closure (i.e., onAudioData: `@Sendable` `@escaping`
(Data) -> Void) so it is safe to cross concurrency boundaries under Swift 6;
update any internal call sites or stored properties that capture the closure to
preserve the `@Sendable` signature and adjust call-site captures if needed.

@shubhammalhotra28
Copy link
Contributor Author

Looks good to merge.
useLocal = True since we can test then - and we still don't have the updated release.

Also, its preferred if someone wants to run local for testing purpose, they'd be using build scripts.

@shubhammalhotra28
Copy link
Contributor Author

@vaibhav936 FYI

@shubhammalhotra28 shubhammalhotra28 merged commit ccdc95d into main Feb 21, 2026
7 of 12 checks passed
ManthanNimodiya pushed a commit to ManthanNimodiya/runanywhere-sdks that referenced this pull request Feb 23, 2026
Mac changes (Changes needed to enable MacOS for distribution)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant