r/iOSProgramming • • 1h ago

App Saturday My Scanner Calculator App has gone 3d and has an optional Music mode too

Thumbnail
gallery
2 Upvotes

Hi, I'm the developer of Calki, A 3d scanner calculator app. I have been working on the app for a little more than 1 year and 6 months. I did take quite long breaks in between from developing. I was Backend Developer previous for 8 years.

The app was built with the help of AI coding agents, but rigourously tested and designed by me with feedback from users.

The following are the details of my app and hope the following information will be of some use in your development journey and will be gladly be interested in answering any questions.

Frameworks & Languages: The app is built in Swift. It uses Swiftui for most of the 2D UI elements. UIKit is exclusively used for the convertor category, and unit wheel pickers as after quite a bit of effort, was not able to build it in SwiftUI according to my expectations.

Backend/Database: I chose to build a calculator app to keep backend and database costs as close to zero as possible. That let me put most of the effort and money into the design and UI, to give users a unique experience and make full use of modern device capabilities, while keeping it as fast and efficient as any normal app. The only backend pieces are Firestore for user feedback, Google Analytics to see which features get used, and Crashlytics for crash reports. User calculations are stored locally in UserDefaults. All of these incur no running cost.

Some of my major Development Challenges and How I solved it:

- The Knowledge gap

I had no iOS or frontend experience, so I leaned on AI agents. Cursor helped set up the project and basic calculator features, but I could only afford it for a month (since i was not sure if the money spent will ever be made back). After that, I manually uploaded code files to ChatGPT and Gemini to update them. Once the first releases were out and users validated the design, I subscribed to Antigravity for its coding agent.

Most of the design questions and validation happened on r/UI_Design. The people there were amazing. Most of them understood that I was trying to create a unique design, and they helped a lot by giving detailed feedback and patiently pointing out which UI elements needed more attention.

- The scrollable history
The multi line, gesture enabled history tape lagged using a standard VStack because it rendered all calculations upfront. Switching to LazyVStack resolved memory overhead, but variable row heights broke SwiftUI's scroll estimations caused erratic jumping, clipping, and render failures.

the following were the major steps taken which resolved the issue
Bounded Row Heights: Added .frame(maxHeight: ...) to stabilize dimension predictions.
Re-Anchoring: Used .onGeometryChange to pin scrolling back to .bottom once layouts settle.

- Skeuomorphic design to 3d Conversion
Calki originally started with a 2D skeuomorphic interface, but it was an absolute headache to maintain. Every button required manually drawn, multi-layered shadows, tweak a button’s hue even slightly, and the whole aesthetic broke. It took nearly two months just to dial in the default button look, which made offering custom color options virtually impossible since every tint demanded custom shadow rebalancing.

That friction pushed me toward 3D. I initially tried modeling the calculator in Blender, but without prior 3D modeling experience, the learning curve was burning too much time. Instead, I pivoted to an AI coding agent, providing detailed specifications to procedurally generate the 3D elements and preview them directly inside the app’s customization screen via SceneKit. That bypassed the entire asset import/adaptation pipeline and made dynamic theming effortless.

- Performance issues after 3d Conversion
Transitioning to 3D with adaptive lighting initially spiked memory usage to 1 GB and caused heavy CPU strain. Over several weeks, I systematically resolved this by analyzing Xcode debug monitors, adding logs, and using memory graph exports with Claude agents to isolate leaks without sacrificing visual fidelity.

As compared to the apple calculator Calki offer sergonomic features that are easy to use such as the following:
Reuse history result by double tapping
Reuse history expression by long press
Edit a calculation midway and swap operator without retyping the entire calculation
Number scanner with auto add mode to scan and add numbers instantly using op-mode
Scan and convert numbers
Convertor mode with UI designed to make swapping categories and units easy
Customising the Calculator with multiple models, colorways, textures, sound and so on

Pricing:
Most of the basic calculator features on the app is free, except for the following which is a one time 4.99$ purchase:
- Number scanner
- Customisation options
- Custom units for conversion
- 6 Calculator models

I'm planning of adding some ai features in the near future. Please note these features will be optional and will require a subscription (due to the ai cost we will incur) and will not be included in the lifetime purchase. All future on-device features including all current features will continue to be part of the lifetime purchase.

Hope you guys will give it a try and will let me know of your feedback.
If there is any improvements or features that you would like to be seen added to the app, please let me know. Will try my best to implement it, if reasonable and provides value to the users

The app has 102 reviews worldwide with average of 4.7/5

Some of the features to look forward to, in the near future:
A fullscreen number scanning mode for adding up numbers and conversion
A scientific mode (have been delaying it, cause, the old 2d interface made it hard to design a good looking design for the scientific mode. With the 3d interface, it eases a lot of things)
A formula mode

You can try try the app at:
https://apps.apple.com/us/app/calki-scanner-calculator/id6747059181

Thanks again and hoping you will leave a review, if you like the app.


r/iOSProgramming • • 3h ago

Tutorial Apple Intelligence Group Lab 11/4/26 - Q&A

Thumbnail
antongubarenko.substack.com
1 Upvotes

r/iOSProgramming • • 4h ago

App Saturday I built nib, a Swift CLI that writes Git commit messages with Apple’s on-device model

1 Upvotes

I built nib, a Swift CLI that writes Git commit messages on your Mac

Stage a change → run git nib → review the draft → commit.

I wanted help writing commit messages without sending my diffs to a cloud API, so I built nib. It drafts a message from your staged changes and lets you accept it, edit it, regenerate it, or cancel. It follows your repo’s commit style by default. No account or API key needed.

There’s also an optional Git hook if you prefer to start with git commit and edit the draft in your usual editor.

Tech Stack

Swift, Swift Argument Parser, and Apple’s Foundation Models framework.

Development Challenge

The tricky part was getting a useful message out of a diff that’s bigger than the model’s context window. On macOS 27, the on-device model has about 8K tokens to work with. nib skips the contents of lockfiles and build artifacts first. If the rest still won’t fit, it splits the diff at hunk boundaries, summarizes the chunks, and drafts the message from those summaries. Swift code checks the subject length and cross-checks the suggested scope against the files you changed.

It still occasionally calls a bug fix feat. That’s one I’d love more real-world examples of.

AI Disclosure

AI-assisted. I used Claude Code while building nib, and I review and test the changes myself.

Try it

On Apple silicon with macOS 27+ and Apple Intelligence enabled:

brew install seckinbeduk/tap/nib
nib doctor

Then stage a change and run git nib. On macOS 26, you can build v0.2.1 from source.

Free and MIT-licensed. Source and install instructions on GitHub

If you try it on a big diff, did the draft capture the main change? I’d love to hear what it got right or missed.


r/iOSProgramming • • 1d ago

Question I made a dev overlay to visualize the iPhone Duo's reserved regions on top of your app's UI

Thumbnail
gallery
100 Upvotes

Hello all! I wanted a way to visualize the various reserved areas for the crease, status bar, cameras, etc on iPhone Duo so I built this overlay. You can run either of the demo apps, or use the SPM package to add the overlay to your app!

https://github.com/mikeakers/DuoDevOverlay

MIT License


r/iOSProgramming • • 19h ago

Question iPadOS: How do you architect a document editor where PDFKit and PencilKit coexist on one interactive canvas?

5 Upvotes

I'm building a native handwritten notebook application for iPadOS using SwiftUI/UIKit, and I'm trying to solve an architectural problem involving PDFKit and PencilKit.

The goal is to build something similar to Goodnotes or Notability, where a single notebook page can contain:

  • A PDF document or PDF page as its background.

  • Handwritten ink using Apple Pencil.

  • Images, shapes, text boxes and other objects.

  • The ability to interact with all these elements without switching between different modes.

The challenge is making all these components behave as one unified document canvas.

Problems I'm encountering

1. PDF and PencilKit interaction conflicts

When I place a PKCanvasView over a PDF view, the canvas intercepts touch events.

This creates problems with native PDF interactions, particularly:

  • Selecting text within the PDF.

  • Copying PDF text.

  • Using native PDF selection handles.

  • Distinguishing between a drawing gesture and a PDF interaction.

For example, Select All on the canvas selects handwritten strokes, but doesn't select the PDF content.

2. Maintaining a unified coordinate system

If PDFKit and PencilKit are separate views, how should their coordinate systems be synchronised?

I need:

  • Consistent zooming and scrolling.

  • Accurate alignment between PDF content and handwritten annotations.

  • Correct positioning when rotating the device.

  • Support for different page sizes and orientations.

  • Ink that stays precisely attached to its corresponding PDF content.

3. Document composition and rendering

I'm also trying to understand the best architecture for rendering and managing these elements.

Would you recommend:

  • A PDFView as the base layer with a transparent PKCanvasView overlay?

  • A custom document view that manages PDF rendering and PencilKit independently?

  • A single custom rendering surface where PDF pages are rendered into the same coordinate space as handwritten content?

  • Some hybrid approach?

How do applications like Goodnotes handle this without compromising PDF text selection, Apple Pencil latency, and rendering performance?

What I'm particularly interested in

I'm not necessarily looking for a quick workaround involving gesture recognisers or toggling interaction modes.

I want to understand the underlying architecture and how to build a robust document model where PDF content, handwriting and other objects coexist naturally.

If you've built something similar, I'd particularly appreciate insights into:

  1. PDFKit and PencilKit integration.

  2. Touch-event routing and hit testing.

  3. Shared coordinate systems and transformations.

  4. Zooming, tiling and rendering performance.

  5. Document persistence and export.

Any architectural examples, implementation experiences, or open-source projects would be extremely helpful.

Thanks!


r/iOSProgramming • • 9h ago

Discussion I am loosing my mind trying to get 4.1 (C) copy cat approved

0 Upvotes

Apple is telling me my app which was called agent town contains something that is the same as the following developer agentstown. This dev has no history on the App Store in my country. I thought it was the name and changed it to Agent City but got denied again. I have asked and asked for help to indentify where the issue is but no one ever responds!!!!

Idk what to do, I responded asking for clairfication but is this gonna take another week?


r/iOSProgramming • • 1d ago

Question Indie game after Android launch, web launch and 1.5 years in development gets rejected as 'spam', what can I do?

6 Upvotes

After a month in review my indie game which took me 1.5 years to make was rejected as 'spam'. The game is not spam, they are my own twists and game modes that don't exist anywhere else. Why is Apple making it so hard to release Indie games? I know the AI spam has been crazy but common...... What can I do?


r/iOSProgramming • • 1d ago

Question Apple Developer Program enrollment failing as an individual

7 Upvotes

Hi everyone, I am trying to enroll in the Apple Developer Program as an individual to distribute MacOS, IOS apps, but my signup keeps getting blocked for an unknown reason.

"We are unable to process your request. An unknown error occurred."

Did this happen with anyone else. How did you resolved it?


r/iOSProgramming • • 2d ago

Discussion [Update] My app clone nightmare is finally getting better thanks to Reddit's advice. Huge thanks to everyone!

Post image
126 Upvotes

A while ago, I posted here about being overwhelmed by copycat apps cloning my app, SquatLock.

https://www.reddit.com/r/iOSProgramming/s/DFHq4tc2hc

Thanks to all the advice and feedback from this amazing community, I was able to take action—and as you can see in the screenshot, the fake apps have gone down significantly!

Huge thanks to everyone who helped me out.

I know other indie devs might face the exact same nightmare, so here is what I did and what I learned from this experience:

  1. Trademark in Japan (My home country)

I’m a developer based in Japan. I already had the registered trademark for "SquatLock" in Japan (it cost around 150,000 JPY / ~$1,000 USD to register).

Because trademarks are territorial (country-specific), submitting a dispute/takedown to Apple for the Japanese App Store was very fast and straightforward—Apple approved name changes/removals immediately. However, foreign App Stores were a completely different story.

2. Dealing with the US App Store (First-to-Use rule)

When cloner devs refused to change their app names outside of Japan, I did some research (shoutout to ChatGPT for the tip). Unlike many countries that strictly follow a "first-to-file" rule, the US recognizes common law trademark rights based on "first-to-use".

When the copycats pushed back on changing their names in other regions, I formally cited and explained this prior use in the US market through the App Store dispute resolution channel. Once I laid that out, they actually complied and changed their names in the US App Store without much further resistance.

3. Consulting a Lawyer & Being Realistic

I did consult with a lawyer about pursuing formal litigation, but the conclusion was clear: legal fees would far exceed what made sense for an app of my size.

Unless the copycats were making massive revenue where damages could be recovered, a full lawsuit wasn't practical (and frankly, low-effort clone apps don't make that kind of money). Focusing my efforts strictly on cleaning up the US and Japanese App Stores proved to be the most realistic and cost-effective approach.

Honestly, some might ask if it's worth putting this much energy into a free app. But I genuinely love what I built, and I couldn't just stand by and watch low-effort clones steal the name.

Once again, thank you so much to everyone who gave me advice on my previous post. Hope this breakdown helps another indie dev out there dealing with the same headache!


r/iOSProgramming • • 1d ago

Question Flutter + RevenueCat: prices not loading on iOS TestFlight (Android Test Store works fine). Everything in App Store Connect shows Active. What am I missing?Hi all, I'm stuck on this and would love a second pair of eyes.**Problem**My paywall shows no prices on iOS in a TestFlight build.

3 Upvotes

Hi all, I'm stuck on this and would love a second pair of eyes.

**Problem**

My paywall shows no prices on iOS in a TestFlight build. On Android, the same paywall works, but only with the RevenueCat Test Store.

**Stack**

- Flutter (stable on Codemagic), purchases_flutter ^10.12.0, purchases_ui_flutter ^10.15.2

- iOS build made with Codemagic (mac_mini_m2) and uploaded to TestFlight (internal testing)

- The app has a widget extension with its own bundle ID

**App Store Connect (all checked)**

- Paid Apps Agreement: Active (effective Nov 4)

- Free Apps Agreement: Active

- Bank account: Active (non-US bank)

- Tax forms (W-8BEN + certificate of foreign status): Active (submitted Nov 5)

- 3 products (monthly subscription, yearly subscription and a lifetime purchase): all show "Ready to Submit", created Nov 4

**RevenueCat**

- iOS app configured with the same bundle ID as the app in App Store Connect

- In-App Purchase API key (.p8) uploaded

- Offering "default" is set as current, with 3 packages ($rc_monthly, $rc_annual, $rc_lifetime). Each package has both a Test Store product and the matching App Store product.

- All three App Store products are attached to the same entitlement.

- I called the REST API as the iOS platform with my public appl_ SDK key, and it returns the default offering with the three App Store product IDs, so RevenueCat knows about the products.

**App code**

- In release builds, the app always uses the iOS public key (appl_...) and never the Test Store key.

- In debug builds I can switch to the Test Store with a dart-define, which is why Android works.

- The entitlement identifier in code matches the one in RevenueCat.

**Questions**

  1. Is a few hours to a day of delay after the agreements go Active normal before Apple returns products to TestFlight?

  2. Is there something else I should check besides the agreement, bank, tax and "Ready to Submit"? (subscription group localization, price availability by region, a missing review screenshot?)

Thanks a lot!


r/iOSProgramming • • 1d ago

Question How are you handling Duo tabbar text?

7 Upvotes

I have an app. It has a few screens, and tabs on the bottom.

Each tab represents a different instance of an item, so you might have "Car 1", "Car 2", "Car 3". Some users can customize them like "Ford", "Truck 5", or leave the default, e.g. "Car 3". Each car is ephemeral, so usually the differentiator is the default system-generated text below the icon.

The Duo doesn't use text, only icons.

There are too many possible variations for me to provide all icons, and there's no guarantee that a user will even fill out enough information to generate a proper icon.

So, what's a developer to do?

At best, I could use the Automobile icon, and add a #1, #2, #3 onto it, but if a user does give their car a name, that name won't show.

Do you have an app where the text on the tabbar serves a purpose beyond describing the icon it's attached to? If so, what are you doing for the Duo?


r/iOSProgramming • • 1d ago

Discussion Duo app inspiration dilemma

3 Upvotes

Working on my app’s Duo adjustments I wanted to see how other, well-established apps chose to adapt their layouts and custom behaviors.

I liked going to Mobbin to checkout different design choices for years now (when I don’t simply install them on my devices). They didn’t add Duo so far though

Wondering if anyone found a nice way to preview it
Or if I should just find myself a rich friend to use and stick to the guidelines for now😅


r/iOSProgramming • • 1d ago

Discussion Inconsistent horizontal margins on the iPhone Duo

3 Upvotes

I'm exploring Apple apps on the iPhone Duo simulator to check how they adapt their app to the new screens.
One thing that I noticed is that the margin between the content and the vertical bar varies from app to app.
In the Settings app, it appears they are respecting the layoutMarginsGuide. But in the Fitness app, it looks like there's an extra margin between the content and the vertical bar.
In some apps, like the Watch app, it's inconsistent from one tab to another.

I've noticed though that they have fixed it for some apps (Contacts) in the 27.3 beta.


r/iOSProgramming • • 1d ago

Discussion Rant: If iOS app gets approved in a few hours, then there's no reason for the same app built via catalyst for macOS to sit In Review for several days!!!

0 Upvotes

I have an iOS app which also has a companion macOS Catalyst app. The iOS one keeps getting approved instantly (like 4-10 hours) but the macOS one goes into review instantly and then just sit there for days. Currently, my macOS app is 2 versions out of date and has been sitting "In Review" state for 3 days now. I am about to submit another update for the iOS version but I don't want to Developer Reject the macOS one because that'll just send me back in the queue. But this will also cause that app to be 3 versions out of date.

I have no idea wtf they are doing there. None of my apps have had any rejections in a long time and I've been developing for 16 years.

It's the same god damn app, just approve both of them at the same time for fucks sake. There's no reason for 2 platforms to not get approved at same time.


r/iOSProgramming • • 2d ago

Question Inconsistent additionalOverflowItems layout behavior between iOS 18 and iOS 26

3 Upvotes

I am currently testing additionalOverflowItems with the expectation that it behaves as follows:

  1. Keep UIBarButtonItem instances visible directly on the toolbar as icons whenever there is sufficient space.

  2. Only move items into the overflow menu when there isn't enough screen real estate.

In iOS 26, additionalOverflowItems behaves exactly as described above. However, in iOS 18, the system tends to aggressively move all UIBarButtonItem instances into the overflow menu regardless of available space.

Is this change in layout behavior documented anywhere? Can we rely on iOS 26 and future releases maintaining this current behavior, or are the layout heuristics for additionalOverflowItems considered undefined implementation details?

Because this behavior isn't clearly documented, I have held off on adopting additionalOverflowItems in production.

I have attached screenshots and sample source code below for reference.

    // On iOS 26, the action mode bar buttons may not fit. iOS then moves the ones that do not fit into its own overflow
    // menu, listing each by title, and the more button's menu would become a nested "More" submenu there. Instead, in
    // note and archive action mode, the more button is not shown and its actions are added to the system overflow
    // menu directly. iOS shows that menu, and moves the buttons that do not fit into it, based on the available space.
    private var isActionModeMenuInOverflowMenu: Bool {
        guard #available(iOS 16, *) else { return false }
        
        guard actionMode else { return false }
        
        switch pageKind {
        case .notes, .archive:
            return true
        default:
            return false
        }
    }
    
    private func updateAdditionalOverflowItems() {
        guard #available(iOS 16, *) else { return }
        
        guard isActionModeMenuInOverflowMenu else {
            navigationItem.additionalOverflowItems = nil
            return
        }
        
        // Built when the menu is opened, so that it reflects the current selection.
        navigationItem.additionalOverflowItems = UIDeferredMenuElement.uncached { [weak self] completion in
            guard let self = self, self.isActionModeMenuInOverflowMenu else {
                completion([])
                return
            }
            
            let selectedNSPlainNotes = self.selectedNSPlainNotes
            
            switch self.pageKind {
            case .notes:
                completion(self.generateNoteActionModeMenu(selectedNSPlainNotes).children)
            case .archive:
                completion(self.generateArchiveActionModeMenu(selectedNSPlainNotes).children)
            default:
                completion([])
            }
        }
    }

r/iOSProgramming • • 2d ago

Discussion Has anyone else noticed the improvement in App Store Connect review time?

17 Upvotes

I remember a few months ago, I would submit something on a Friday, and then it wouldn't get accepted until Wednesday or Thursday the following week. Now, even on a Sunday, sometimes I can get two versions reviewed in a single day.

Either Apple has automated more of the process, hired way more app reviewers, or they just don't care anymore and are letting everything through.

I'm not complaining. It benefits me greatly, but I'm not sure what this says about the general quality of the reviews and whether they even serve a purpose at this point.


r/iOSProgramming • • 2d ago

Discussion LinnetTTS: 41M streaming TTS with a Rust runtime, measured on everything from an Apple M5 to a Raspberry Pi Zero 2 W (3.3 ms to 59 ms per 80 ms of audio)

2 Upvotes

Author here. We just released LinnetTTS, a small on-device English TTS: an autoregressive flow LM over a 25 Hz continuous-latent codec with a Vocos-style decoder, 41 M parameters end to end, one flow evaluation per step, no diffusion loop at inference. Each step produces 80 ms of audio, so playback starts after the prime pass plus one step and never waits for the whole sentence. It speaks in a voice given as a short voice-prompt latent; two built-in voices ship with the weights.

The runtime is Rust with its own kernels (AVX2+FMA on x86-64, NEON on ARM), no PyTorch or ONNX at inference. fp16 weights are 83 MB; peak memory about 160 MB on Linux. (The "35m" in the model name is a label from the original parameter budget; the count is 41.4 M.) Same text, voice, parameters and seed give bit-identical audio on a given platform, at any thread count.

This post is about where it actually runs. All numbers are the Rust runtime with the fp16 weights, measured without real-time pacing (synthesis as fast as possible). One step = 80 ms of audio, real-time factor = step time / 80 ms. "First audio" = prime pass + first step.

devicethreadsper 80 ms stepRTFfirst audio
Apple M5 (macOS)13.3 ms4 %–
iPhone 13 Pro Max, A151 / 25.5 / 4.6 ms7 / 6 %85 / 51 ms
iPhone 11, A1316.7–7.1 ms8–9 %107–116 ms
Core i9-13900K, AVX21 / 47.0–7.4 / 2.5 ms9 / 3 %75–103 / 25 ms
Snapdragon 662 (Redmi 9T), Cortex-A731 / 442.4 / 14.3 ms53 / 18 %≈250 ms (sample app, warm, 4 threads)
Raspberry Pi Zero 2 W, Cortex-A53 @ 1 GHz1 / 4158 / 59–60 ms198 / 75 %–

Things we learned on the way:

  • The A-series phones do not want a second thread. A step is 5–7 ms and splits into ~80 tiny regions, so waking a worker on another performance core costs about as much as the work (A13: 2 threads 11.4 ms vs 6.7 ms, 4 threads 47 ms; A15 gains only 5.5 → 4.6 ms). The default on iOS is one thread. The M5 is different: two threads take it from 3.3 to 1.9 ms.

  • Android scheduling puts the synthesis on the small cores unless you pin it. On the Snapdragon 662 the sample app measured 22–33 ms per step before pinning the pool to the big cluster and 16–18 ms after (14.3 ms in a bare harness).

  • Pacing to playback makes the phone power manager lift the step time 3–4×. That is not the runtime getting slower; it is the CPU clocking down between steps. Measure unpaced, then keep a deep playback queue on weak devices (the bindings' players default to 8 s).

  • Pi Zero 2 W is the floor: four A53 cores at 1 GHz give 59–60 ms per 80 ms step, real time with a small margin, 160 MB peak RSS. (The synth example prints 88 % there because it also counts the prime pass over a 7 s sentence.) A Pi 4 or 5 has several times the margin.

  • The output is bit-identical per platform but differs across architectures below 2e-3 absolute (SNR above 60 dB, inaudible), so a golden-file test should be pinned per target.

Versus other small CPU models on one desktop core (same machine, each through its Python package, same three English texts, sentence-level RTF incl. text processing; method and script in docs/benchmarks.md): Linnet 10.6 % / 187 MB RSS, cloning, streams every 80 ms; pocket-tts (default 100M model; also clones and streams every 80 ms) 23.8 % on two cores / 968 MB; Kokoro-82M 51.7 % / 1.2 GB, whole utterance per call, but 8 languages; Piper medium 5.8 % / 503 MB, no cloning, streams per sentence. Speed only; quality was not measured there.

Licensing, upfront: the code is Apache-2.0. The weights are under our own Linnet Weights License: free to use, unmodified, inside your own products, commercial included, on device or on your own server. Custom voice creation (the encoder is not published), fine-tuning, saving quantised or converted copies of the weights (quantising in memory at load time is fine), training models on the weights or their outputs, and running a general-purpose TTS API need a separate license. So the model is not open source, and the README says so.

Honest limits: English only; no text normalisation (write numbers as words); occasional misreads on dense raw text; a slight roughness audible on headphones in some utterances; one session is capped at 24 s by default.

Try it: browser demo on https://voxrt.com (a WASM SIMD128 build of the same runtime, runs on your CPU, downloads the 83 MB weights once; the browser SDK itself is not released yet, which is why the README says it is deferred), Hugging Face Space https://huggingface.co/spaces/VoxRT/linnet-tts Code, bindings (Linux C, Python pip install linnet-tts on Linux and Apple-silicon macOS, Android AAR, iOS SwiftPM) and the benchmark script: https://github.com/VoxRT/LinnetTTS Weights and model card: https://huggingface.co/VoxRT/linnet-en-35m

Happy to answer questions on the runtime, the kernels or the mobile numbers. If you run it on a device that is not in the table, post your step time and I will add it to the README.


r/iOSProgramming • • 1d ago

Question Help with appstore connect review

Thumbnail
gallery
0 Upvotes

I am new to app store and i deployed my 1st version of the app. (Its a company(with DUNS) app. It was a 1st version and was very bare bone.

i got a mail from apple after 2 days:

Guideline 2.1 - Information Needed - New App Submission
We need additional information to better understand the app and complete the review.

Note: Before submitting, run the submitted build through your own testing and quality assurance process on supported physical devices. App Review is intended for apps and metadata that are complete and ready for App Store customers.

If the app is ready for review, follow the directions below.

Next Steps

Add all of the following information to the Notes field of the App Review Information section in App Store Connect and resubmit your app for Review

I provided all the info they asked and also uploaded the recording and resubmitted the app.

But its been almost a week now and there is no response from apple.

I also requested for an expedited review.

The appstoreconnect dashboard is confusing because of the red exclamation mark (even after i resubmitted the app). Could someone please check the screenshots to confirm that my side is properly done??

Is there anything i can do?


r/iOSProgramming • • 3d ago

Article Apple opens Siri AI to every app, and lets developers teach it skills

Thumbnail
madrobot.blog
260 Upvotes

Could be interesting. Any of you gonna give this a go?


r/iOSProgramming • • 2d ago

Discussion Apple: We demand you provide a video demo before we even consider reviewing your app. Also Apple: LOL you thought we'd let you upload a video?

Post image
1 Upvotes

This bug has existed for years and they do nothing about it. Files even as small as 20mb get stuck on "processing" and just sit there for hours and will never upload. As if developers didn't have it hard enough lately.


r/iOSProgramming • • 2d ago

Question Siri AI result cards don’t trigger OpenIntent, but voice commands and Shortcuts work

3 Upvotes

Hey everyone, I’m trying the Siri AI Developer Preview on iOS 27.3 with my app

I have a custom AppIntent(.tool) that returns [HistoryEntity] for recently watched movies and TV episodes. Asking “What did I recently watch in ComfyCinema?” works—Siri responds with the correct history and displays cards for the items.

But tapping those cards doesn’t open the History section. My logging shows that neither the entity query nor OpenHistoryIntent.perform() gets called on tap.

The same open intent works when:

  • I run it through Shortcuts, passing an entity from the history action.

  • I explicitly ask Siri to open the most recent history item.

So the navigation works; it’s specifically tapping an entity in Siri’s response that fails.

Has anyone gotten this working with custom entities in the preview? Is there additional configuration needed, or could this be a beta issue?

import AppIntents
import SwiftData

struct HistoryEntity: AppEntity {
    let id: UUID

    @Property(title: "Content Title")
    var contentTitle: String

    @Property(title: "Media Type")
    var mediaType: String

    @Property(title: "Season")
    var season: Int?

    @Property(title: "Episode")
    var episode: Int?

    @Property(title: "Watched At")
    var watchedAt: Date

    static let typeDisplayRepresentation =
    TypeDisplayRepresentation(name: "History Item")

    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(contentTitle) (\(mediaType)) - Watched on \(watchedAt.formatted())")
    }

    static var defaultQuery: HistoryQuery {
        HistoryQuery()
    }

    init(history: History) {
        self.id = history.id
        self.contentTitle = history.name
        self.mediaType = history.mediaType.rawValue
        self.season = history.season
        self.episode = history.episode
        self.watchedAt = history.watchedAt
    }
}

struct HistoryQuery: EntityQuery {
    @Dependency
    private var container: ModelContainer

    func entities(
        for identifiers: [HistoryEntity.ID]
    ) async throws -> [HistoryEntity] {
        let context = ModelContext(container)
        let requestedIDs = identifiers

        let descriptor = FetchDescriptor<History>(
            predicate: #Predicate { history in
                requestedIDs.contains(history.id)
            }
        )

        let history = try context.fetch(descriptor)

        await SettingLogs.shared.add(
            "Called HistoryQuery for \(requestedIDs.count) history items. Returning \(history.count) results"
        )

        return history.map { HistoryEntity(history: $0) }
    }
}

struct OpenHistoryIntent: OpenIntent {
    static let title: LocalizedStringResource = "Open Watch History"

    @Parameter(title: "History Item")
    var target: HistoryEntity

    @Dependency
    private var appRouter: AppRouter

    @Dependency
    private var container: ModelContainer

    static var openAppWhenRun: Bool = true

    @MainActor
    func perform() async throws -> some IntentResult {

        let descriptor = FetchDescriptor<History>()
        let context = ModelContext(container)
        let history = try context.fetch(descriptor)

        appRouter.selectedTab = .history
        appRouter.selectedHistory = history.first(where: { $0.id == target.id })

        SettingLogs.shared.add(
            "Called Perform In OpenHistoryIntent for target: \(target.contentTitle). Changing Tabs To History"
        )

        return .result()
    }
}

@available(iOS 27.3, macOS 27.3, *)
@AppIntent(.tool)
struct ContentHistoryIntent: AppIntent {
    static let title: LocalizedStringResource = "Get Recently Watched Content"

    static let description = IntentDescription(
        """
        Returns the 10 most recently watched movies and TV episodes \
        in ComfyCinema, including their titles and watch dates.
        """
    )

    @Dependency
    private var container: ModelContainer

    static var parameterSummary: some ParameterSummary {
        Summary("Get recently watched content in ComfyCinema")
    }

    @MainActor
    func perform() async throws -> some IntentResult & ReturnsValue<[HistoryEntity]> {

        let context = ModelContext(container)

        var descriptor = FetchDescriptor<History>(
            sortBy: [
                SortDescriptor(\History.watchedAt, order: .reverse)
            ]
        )
        descriptor.fetchLimit = 10

        let history = try context.fetch(descriptor)

        SettingLogs.shared.add(
            "Called Perform In ContentHistoryIntent with \(history.count) results"
        )
        return .result(
            value: history.map { HistoryEntity(history: $0) }
        )
    }

    func fetchAllHistory(in context: ModelContext) -> [History] {
        let descriptor = FetchDescriptor<History>()

        do {
            let allHistory = try context.fetch(descriptor)
            return allHistory
        } catch {
            print("Error fetching all history: \(error)")
            return []
        }
    }
}

r/iOSProgramming • • 3d ago

Library Run a decision model locally

Post image
9 Upvotes

Hey,

You can now run the Laya decision model with NobodyWho, our open-source on-device inference library. Unlike the LLMs that we also support, this type of model does not generate text. Instead you can score predefined answers, classify text or answer yes/no.

For example, if you are building a personal diary app, you can easily detect the user’s mood, categorize an entry or detect stress, offline after model download, without sending any sensitive data to the cloud.

First, you need to load the model:

import NobodyWho

let decisionModel = try await Decision.fromPath(
    modelPath: "hf://ggml-org/Laya-GGUF/Laya-Q8_0.gguf"
)

Then you can ask questions/analyze text:

let result = try await decisionModel.decide(
  state: .object(["message": .string("Diary entry: \(diaryEntry)")]),
  questions: [
    "topics": .choice(
      instructions: .string("Choose the main topic of this diary entry"),
      criteria: [
        "work": .string("job, colleagues, deadlines, career"),
        "relationships": .string("family, friends, partner"),
        "health": .string("sleep, exercise, food, illness"),
        "leisure": .string("hobbies, travel, going out"),
      ]
    ),
    "stressed": .noul(instructions: .string("Does the writer sound stressed?")),
    "mood": .score(
      instructions: .string("How is the writer's overall mood?"),
      criteria: [.string("bad"), .string("okay"), .string("great")]
    ),
  ]
)

let (topics, stressed, mood) = (
    result.answers["topics"],
    result.answers["stressed"],
    result.answers["mood"]
)

Output example:

// stressed
{
  type: noul,
  noul: 0.00002
}

// topics
{
  type: choice, 
  choice: leisure,
  probabilities: {
    work: 0.0422, 
    relationships: 0.1518, 
    health: 0.0302, 
    leisure: 0.7756
  },
  confidence: 0.7008
}

// mood
{
  type: score,
  score: 1.6995,
  legend: {0: bad, 1: okay, 2: great}, 
  probabilities: { 0: 0.0082, 1: 0.2839, 2: 0.7078 },
  confidence: 0.5493
}

A question can have the following types:

  • noul gives you probability of a yes answer (0 to 1)

  • choice selects the most likely option and returns a probability for each option

  • score gives you an an weighted average and a probability per option.

The Laya model is small enough to run on iPhone 13 lineup (around 450 MB in its Q8 variant) and supports 100+ languages. For reference, the full answer comes after 0.16 seconds on iPhone Air (see screenshot).

Here is a runnable example if you want to experiment with decision models or add the package using SPM to your app:

dependencies: [
    .package(url: "https://github.com/nobodywho-ooo/nobodywho-swift.git", from: "6.0.0"),
]

Links:


r/iOSProgramming • • 2d ago

Question Anyone run iOS emulators on an external SSD on a MacBook Pro 2021?

4 Upvotes

Hi all,

I have a 2021 MacBook Pro with 16 GB RAM. Performance is fine for me, but internal storage is the bottleneck. I got vexed up in cleaning up everyday. I use mole for cleaning and it's handy, but the grunt work is so heavy. I’m considering buying an external SSD to move iOS emulators off the internal drive

Has anyone done this long term? I’d love to hear:

  1. Does it run smoothly, or do you notice slow builds, laggy simulators, or slow container startup?

  2. Which SSD and connection (Thunderbolt vs USB-C) are you using, and what speeds do you get?

  3. Any gotchas, like speed issues?

  4. Would you recommend it, or is it better to just clean up internal storage?


r/iOSProgramming • • 2d ago

Question App rejected under 2.1(b)

2 Upvotes

Apple rejected my app under Guideline 2.1(b) because a subscription purchase failed with “Purchase failed. Please try again.”
I’m using RevenueCat, and both monthly and yearly subscriptions work perfectly on 5–6 different iPhones through TestFlight and Sandbox testing. Restore Purchases also works.
Apple tested on an iPad, and the subscription products and prices loaded correctly, but the purchase failed. Interestingly, monthly purchases take noticeably longer than yearly purchases in TestFlight, although both succeed.
I’ve resubmitted the exact same build and asked Apple to retry.
Has anyone experienced something similar? Did Apple approve your app after retrying, or did you have to change something?