RORK LABJP
FUNDING — Rork raises a $15M seed led by Left Lane CapitalRORK MAX — Rork Max generates native Swift apps instead of React NativePLATFORM — It targets iPhone, iPad, Watch, and Vision Pro, reaching Live Activities and Core MLGROWTH — Traffic keeps climbing at 743K monthly visits and 85% growthTEST — The Companion app lets you test on a real device without a paid Apple Developer accountSTACK — Built on React Native and Expo for true native experiences, not web wrappersFUNDING — Rork raises a $15M seed led by Left Lane CapitalRORK MAX — Rork Max generates native Swift apps instead of React NativePLATFORM — It targets iPhone, iPad, Watch, and Vision Pro, reaching Live Activities and Core MLGROWTH — Traffic keeps climbing at 743K monthly visits and 85% growthTEST — The Companion app lets you test on a real device without a paid Apple Developer accountSTACK — Built on React Native and Expo for true native experiences, not web wrappers
Articles/App Dev
App Dev/2026-06-30Intermediate

Building a Native Bluetooth Pairing Sheet with AccessorySetupKit

iOS 18's AccessorySetupKit lets you pair a single, specific device through a system sheet without the broad Bluetooth permission prompt. Assuming the native Swift that Rork Max generates, here is the path from declaration to picker to connection, with working code.

AccessorySetupKitBluetoothiOS 185Rork Max195CoreBluetooth

Premium Article

Trying to connect a peripheral from my own app, the broad "App Name would like to use Bluetooth" dialog would pop up right at launch — and for a while I buried the connect feature deep in a settings screen just to avoid it. As an indie developer running utility apps on the App Store for years, I know a wide permission request in the first few seconds cools the whole experience down.

iOS 18's AccessorySetupKit changes that premise. Instead of asking for access to all of Bluetooth, your app lets the user pick just the target device inside a system-drawn sheet. Only the chosen device is authorized, and the broad permission dialog never appears. Assuming the native Swift Rork Max generates, we will walk from declaration to picker to connection. (This feature requires a native implementation; plain React Native cannot do it.)

Why you avoid asking for "everything"

Classic CoreBluetooth asks for Bluetooth permission the moment you start scanning — from the user's view, a broad "can this app see nearby devices?" grant. AccessorySetupKit inverts this: it narrows the unit of permission down to this one device.

The user picks the nearby target inside a system sheet. Your app receives the identifier of the chosen device and can connect to that device only. You never ask for a broad scan permission, so the first experience stays intact — which matters most when, like an indie developer, you are building trust from scratch.

The required declarations (Info.plist)

First declare "what kind of device you handle" in Info.plist. Miss this and the picker is silently empty.

<key>NSAccessorySetupKitSupports</key>
<array>
  <string>Bluetooth</string>
</array>
<key>NSAccessorySetupBluetoothServices</key>
<array>
  <!-- List every service UUID your device advertises -->
  <string>0000FE2C-0000-1000-8000-00805F9B34FB</string>
</array>

Even in a Rork Max project, add these two keys to the native Info.plist. List every service UUID the target advertises under NSAccessorySetupBluetoothServices; devices whose UUID is missing here never appear in the sheet.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A system picker that surfaces only your specific device, built with ASAccessorySession and ASDiscoveryDescriptor (working Swift)
How to avoid the broad Bluetooth permission dialog and still connect via CoreBluetooth without a prompt afterward
Info.plist NSAccessorySetupKitSupports / service-UUID declarations and how to handle added / renamed / removed events
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

App Dev2026-06-30
Screening Images On Device Before They Appear — Notes on SensitiveContentAnalysis
Implementation notes on blocking inappropriate images before they render, right on the device, for apps that handle AI-generated or user-submitted photos. Covers calling Apple's SensitiveContentAnalysis framework from Swift and wiring it into Rork Max native code or an Expo native module, with the pitfalls I actually hit.
App Dev2026-06-28
Design On-Device Core ML So Cold Start and Heat Don't Break It
Put on-device Core ML in the native Swift that Rork Max generates and you hit two walls before accuracy: the first inference is slow, and the device heats up and slows down. Here is a design built around cold start and a thermal budget, with working Swift.
App Dev2026-06-28
Building a Live Barcode and Text Scanner in Rork Max with VisionKit's DataScanner
Add a live barcode and text scanner to your Rork Max native Swift app using VisionKit's DataScanner. Covers the SwiftUI bridge, availability handling, throttling repeated detections, and on-device verification with working code.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →