OpenAI-Wrapper-SwiftUI: The iPhone AI app that never ships your API key

A SwiftUI vision wrapper built around a proxy-first trust boundary, automatic camera prompting, and a deliberately boring backend that makes mobile AI safer to ship.

8 min read • View on GitHub • More from adamlyttleapps

A wide editorial scene shows an iPhone camera on the left, a small proxy server in the center, and an OpenAI cloud on the right. A sealed key stays behind the server while a request line moves from the phone toward the cloud, explaining that the app keeps the secret off the device.
The app’s real feature is not the chat UI. It is the boundary that keeps the key on the server.
Key Takeaways

The hidden product is the trust boundary

The obvious label for this repo is wrong. It is not just a SwiftUI wrapper around OpenAI, it is a small argument about where trust should live on a phone. The app keeps the camera and chat on device, but pushes the secret across a proxy boundary, which is exactly where a mobile API key should live.

AIWrapper-SwiftUI is a SwiftUI-based wrapper designed to leverage AI for vision-related tasks. This wrapper interacts with an OpenAI proxy script to secure API communications and protect your API key

GitHub Repository README, Source Documentation · OpenAI-Wrapper-SwiftUI README

That is the cleanest way to read the project. On iOS, binaries are easy to inspect and secrets are hard to hide, so the safest move is often to remove the secret from the client entirely. Adam Lyttle’s repo is interesting because it treats the backend as the lock, not the UI as the fence.

A WSJ hedcut-style portrait of Adam Lyttle rendered in black ink on a pure white background. The portrait is based on his GitHub avatar and preserves his likeness while using stipple texture for skin and fine hatching for hair and clothing.

From camera to question, in one motion

The app does not begin with a blank composer. It begins with `CameraView`, which wraps `AVCaptureSession`, captures an image, and hands that image straight into the chat flow. That matters because the first interaction is not typing, it is asking the model to interpret what the camera already saw.

A medium editorial scene shows an iPhone camera aimed at a tabletop object, with the interface snapping into a ready state as soon as the photo is captured. The composition explains how the app turns a camera frame into an immediate question instead of waiting for the user to type.
The interaction model is a reflex. Capture first, ask second.

The repo’s point is not that the phone can talk to a model. Plenty of wrappers do that. The point is sequencing. The camera makes the app feel like a tool with intent, and the automatic prompt turns vision into the default mode instead of an edge case.

Update the Proxy Script Location:In the Models >> ChatModel class, update the location property with the URL of your OpenAI proxy script. The source code for the openai_proxy.php script used in the demo is available at:https://github.com/adamlyttleapps/OpenAI-Proxy-PHP.

GitHub Repository README, Source Documentation · OpenAI-Wrapper-SwiftUI README

How the proxy-first pipeline works

The architecture is the product. The proxy is where the secret stays, the phone is where the interaction lives.

The architecture is simple on purpose. The phone captures, resizes, and encodes the image, then sends a request to a PHP proxy, which validates the shared-secret logic and forwards the call to OpenAI. The response comes back through the same boundary, so the client never needs to know the API key at all.

if let image = self.image,
   let resizedImage = self.resizedImage(image),
   let resizedImageData = resizedImage.jpegData(compressionQuality: 0.4) {
    // build and send the proxy payload
}

That is the real engineering choice here. The repo uses a shared-secret style check, and the research notes that the hash is MD5, which is not strong cryptography but is enough to act as a lightweight gate in front of the proxy. The important part is not pretending this is airtight security. The important part is refusing to ship the actual OpenAI key inside the app.

Why the UI stays fast enough to feel native

A close-up editorial scene shows a large raw photograph passing through a narrow gate and emerging as a smaller, lighter packet on the other side. The image explains how the app trims payload size before the request leaves the phone, which keeps latency and cost under control.
The app is opinionated about payload size. Smaller images are cheaper, faster, and easier to move through the proxy.

The same practical mindset shows up in the client code. `ScrollViewReader` keeps the conversation pinned where it should be, `UserDefaults` stores lightweight history metadata, `FileManager` handles the heavier image assets, and background writes keep the interface from stuttering after a send. None of that is glamorous, but it is the difference between a demo and something people can actually use.

A medium-close editorial scene shows a filing drawer split into two compartments, with thin metadata cards in one side and image files in the other. The composition explains the split between lightweight chat history storage and heavier photo persistence on disk.
The app separates small records from large assets. That keeps history manageable without slowing the chat view.

That storage split is easy to overlook, but it is one reason the wrapper feels product-shaped. The app is not just moving pixels around. It is keeping the conversation, the camera output, and the saved history in different places so the UI can stay responsive while the model work happens elsewhere.

The comparison that explains the design

A wide side-by-side editorial scene contrasts two ways to ship mobile AI. On the left, a developer stuffs a key into a phone and tries to hide it in the app. On the right, the same developer routes requests through a proxy box with the key locked away, making the safer architecture feel visibly cleaner.
General-purpose SDKs can get you to the API faster. This repo shows the architectural pattern that keeps the key out of the app.
ProjectAPI key handlingPrimary use caseProxy required?Vision-first?Best for
OpenAI-Wrapper-SwiftUIKey stays off-device and lives behind a proxyCamera-driven SwiftUI vision appsYesYesTeams that want a secure mobile pattern
OpenAISwiftDeveloper manages the key in the app or backend setupGeneral OpenAI client accessNo built-in proxyNoApps that want a broad Swift client
MacPaw/OpenAIDeveloper manages the key in the app or backend setupGeneral-purpose OpenAI integrationNo built-in proxyNoTeams that want a maintained SDK

That table is the whole argument in miniature. The broader clients are useful if you want a general SDK, but they do not give you this repo’s opinionated security shape. OpenAI-Wrapper-SwiftUI is narrower on purpose, and that narrowness is what makes it valuable.

What this repo is really teaching

The lesson here is bigger than SwiftUI and bigger than OpenAI. Once AI moves onto the phone, architecture becomes part of the user experience, because the place you store a key determines how safely you can ship the feature at all. This repo is a compact pattern for secretless mobile AI: camera on device, intelligence in the cloud, and the secret parked behind a boring intermediary that does its job without being seen.

That is why the project feels more useful than a typical wrapper. It is not trying to win on breadth, or out-feature a general SDK, or invent a new chat metaphor. It is showing one clean way to build an iPhone AI app that can see, talk, and stay secretless at the same time.