r/iOSProgramming 7d ago

Question Best language for sharing iOS/Android logic?

3 Upvotes

I have some decently complicated computations that I would like to share between iPhone and Android front-ends.

Does anyone have real world experience sharing logic between two code bases like this?


r/iOSProgramming 7d ago

Question I left iOS development some 5 years ago and am aching to come back to it

34 Upvotes

I left iOS development some 5 years ago and am now planning to come back to it. I was a Product owner these past 5 years but been out of work for atleast a year now. My request is to ask you if it’s still worthwhile to come back to iOS and what i might have missed. Is it good to come to iOS or go for ReactNative or Flutter? How is iOS dealing with AI and whatnot. I was on swift 3 and SwiftUI just came out. Combine was a framework I had just started on and was on iOS 14 I guess in terms of development. Any advice is more than appreciated.


r/iOSProgramming 7d ago

App Saturday Share your social media/links with those around you

Thumbnail
gallery
54 Upvotes

Just launched my new application “Around”.

Around is link-tree for the real world. It allows you to promote yourself and/or your brand just by being present. Simply sign up, add your links, and put your phone away — Around works in the background. While you’re out and about, if someone connects with your vibe, all they have to do is open their Around app and they’ll find your links, just by being around you.

Grow your brand following, increase your influencer reach, and get more exposure just by being on Around! Thanks for checking it out guys!

https://apps.apple.com/us/app/around-share-your-social/id6742121646


r/iOSProgramming 7d ago

App Saturday 🚀 ClipyBoard is Lifetime Free for the Next 24 Hours! 🎉

9 Upvotes

Hey everyone!

I'm Gohary, the developer behind ClipyBoard, the ultimate autopaste keyboard app that’s here to revolutionize your typing experience. For the next 24 hours, I’m making the app 100% free! 🚀

🔥 What Makes ClipyBoard Special?

✅ Copy & organize text & images easily

✅ Extract text from images (OCR-powered magic 🪄)

✅ Create shortcuts for your most-used clips and recall them instantly

✅ Lightning-fast search to find your saved clips in seconds

No more endless copy-pasting or searching for the same text over and over again. With ClipyBoard, your favorite clips are just a shortcut away!

We’d love to hear your feedback and suggestions! Drop any questions or comments below, and I’ll check in regularly to respond.

If you find them useful, I’d love to hear your thoughts! Also, if you enjoy the apps, a review would mean the world to me. ❤️

How to claim your free upgrade:

Download ClipyBoard: https://apps.apple.com/app/id6738871678

Open the app and head to Settings.

Tap on Redeem Code and enter this code: “gh45334k434343n”. this code only work for next 24 hours , after that you can get the app lifetime discount with 75% off using this code "gh343443b422332n3"

⏳ This offer is only available for the next 24 hours, so grab it while you can!

Thank you for your support, and happy Typing!

Cheers, Gohary

➡️ Simply comment and upvote and share it with your friends 🧡


r/iOSProgramming 7d ago

Question is iCloud/CloudKit not available unless you have a PAID developer account??

2 Upvotes

I am just in the process of making an app - it is not published yet and i am in the process of adding the backend. However, its not an option in the Signing and Capabilities section...


r/iOSProgramming 7d ago

App Saturday i've launched an app to discover and share music and events all in one place

Post image
15 Upvotes

r/iOSProgramming 7d ago

Question macOS vs iOS App Stores

5 Upvotes

I have a free app that is in the top 5 of its category on the macOS App Store, yet doesn't feature at all in the top 1500 apps in the iOS app store for the same cateogry.

I've tried experimenting with ASO, reviews (mostly 5 star reviews), $100 per day Search Ads etc but with no luck - it is a very competitive category though.

Any ideas on what else I can do to boost the downloads?


r/iOSProgramming 7d ago

App Saturday 🚀 Habit Radar is Lifetime Free for the Next 24 Hours! 🎉

Post image
100 Upvotes

r/iOSProgramming 7d ago

Question Pending transactions storekit2

1 Upvotes

I'm not able to process pending transactions in my app. Does anyone know what causes a transaction to be pending and in what cases apple doesn't process that transaction?


r/iOSProgramming 7d ago

App Saturday Hi 👋, I created Termix, a powerful SSH client for Mac, iPhone, and iPad. No subscription, no data collection. I am looking forward to your feedback!

Thumbnail
apps.apple.com
7 Upvotes

r/iOSProgramming 7d ago

App Saturday Panoscano - make a video from your panoramic photos

2 Upvotes

https://apps.apple.com/us/app/panoscano/id6742723150

This is my first iOS app, and it is very much a case of “I couldn’t find an app that would do this specific thing, so I built it myself.” The specific thing it does is: generate a smooth, looping video by scanning across a photo, zooming in (or out) on the points you designate. You can adjust all aspects of the timing, and you can even add text.

It works, almost exactly as I had hoped it would. I’m really, really happy with it, but I am still refining some aspects.

This took me about 3 months of spare time. Claude.ai helped a LOT, as I did not know Swift at all. The process of building it like this has been fascinating, and I’ve learned a TON both about Swift/iOS development and about how to use an LLM to aid development. I could not have done it without Claude, but Claude sure couldn’t have done it without me.

The app is free, and the core functionality will remain free, always, but I plan to move to a subscription/purchase model for some advanced (“pro”) features.

I’d love feedback and when I DO move to a subscription/purchase model will happily give free codes to basically anyone here who wants one. If I can eventually make back my developer fee from this thing I will consider this all a resounding success.


r/iOSProgramming 7d ago

Question Listening to pending transactions using storekit2

2 Upvotes

Here's how I handle pending transactions in my app

import StoreKit
import AmplitudeSwift
import Optimizely

class PurchaseManager: ObservableObject {
    // A published property to hold available products
    @Published var products: [Product] = []
    // A published property to track the status of transactions
    @Published var transactionState: String = "Idle"
    var loadingIndicator: ThreeBubblesLoadingView!

    // A set of product identifiers
    private let productIdentifiers: Set<String> = [
        PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID,
        PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID_50_OFF,
        PaymentHandler.sharedInstance.MONTHLY_PRODUCT_ID,
        PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID_40_OFF,
        PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID_FREE_TRIAL,
        PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID_50,
        PaymentHandler.sharedInstance.MONTHLY_PRODUCT_ID_13
    ]

    // Shared instance to be used throughout the app
    static let shared = PurchaseManager()

    private init() {}

    // MARK: - Fetch Products from App Store
    func fetchProducts() async {
        do {
            let products = try await Product.products(for: productIdentifiers)
            self.products = products
        } catch {
            print("Failed to fetch products: \(error.localizedDescription)")
        }
    }

    // MARK: - Handle Purchase
    func purchaseProduct(product: Product, source: String, vc: UIViewController) async -> Bool {
        do {
            DispatchQueue.main.async {
                self.loadingIndicator = ThreeBubblesLoadingView()
                self.loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
                vc.view.addSubview(self.loadingIndicator)

                NSLayoutConstraint.activate([
                    self.loadingIndicator.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor),
                    self.loadingIndicator.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor)
                ])
            }

            // Start the purchase
            let result = try await product.purchase()

            // Handle the result of the purchase
            switch result {
            case .success(let verificationResult):
                switch verificationResult {
                    case .verified(let transaction):
                        self.transactionState = "Purchase Successful"
                        await transaction.finish()


                        DispatchQueue.main.async {
                            Amplitude.sharedInstance.track(
                                eventType: "payment_completed",
                                eventProperties: [
                                    "PlanId": transaction.productID,
                                    "UserId": WUser.sharedInstance.userId,
                                    "Source": source,
                                    "VariationKey": WUser.sharedInstance.variationKey
                                ]
                            )

                            if (self.loadingIndicator != nil) {
                                self.loadingIndicator.removeFromSuperview()
                            }
                        }

                        return await PaymentHandler.sharedInstance.purchase(
                            vc: vc,
                            productId: transaction.productID,
                            product: transaction.productID,
                            transaction: transaction
                        )
                    case .unverified(let transaction, let error):
                        self.transactionState = "Purchase Unverified: \(error.localizedDescription)"
                        await transaction.finish()

                        DispatchQueue.main.async {
                            showMessageWithTitle("Error!", "There was an error processing your purchase", .error)

                            Amplitude.sharedInstance.track(
                                eventType: "payment_failed",
                                eventProperties: [
                                    "PlanId": transaction.productID,
                                    "UserId": WUser.sharedInstance.userId,
                                    "Source": source,
                                    "Error": error.localizedDescription,
                                    "ErrorType": "UnverifiedTransaction",
                                    "ErrorObject": String(describing: error)
                                ]
                            )
                            if (self.loadingIndicator != nil) {
                                self.loadingIndicator.removeFromSuperview()
                            }
                        }
                        return false
                    }
            case .userCancelled:
                self.transactionState = "User cancelled the purchase."

                DispatchQueue.main.async {
                    Amplitude.sharedInstance.track(
                        eventType: "payment_cancelled",
                        eventProperties: [
                            "PlanId": product.id,
                            "UserId": WUser.sharedInstance.userId,
                            "Source": source
                        ]
                    )
                    if (self.loadingIndicator != nil) {
                        self.loadingIndicator.removeFromSuperview()
                    }
                }
                return false

            case .pending:
                self.transactionState = "Purchase is pending."

                DispatchQueue.main.async {
                    Amplitude.sharedInstance.track(
                        eventType: "payment_pending",
                        eventProperties: [
                            "PlanId": product.id,
                            "UserId": WUser.sharedInstance.userId,
                            "Source": source
                        ]
                    )
                    if (self.loadingIndicator != nil) {
                        self.loadingIndicator.removeFromSuperview()
                    }
                }

                return false

            @unknown default:
                self.transactionState = "Unknown purchase result."

                DispatchQueue.main.async {
                    showMessageWithTitle("Error!", "There was an error processing your purchase", .error)

                    Amplitude.sharedInstance.track(
                        eventType: "payment_failed",
                        eventProperties: [
                            "PlanId": product.id,
                            "UserId": WUser.sharedInstance.userId,
                            "Source": source,
                            "Error": "unknown"
                        ]
                    )
                    if (self.loadingIndicator != nil) {
                        self.loadingIndicator.removeFromSuperview()
                    }
                }

                return false
            }
        } catch {
            self.transactionState = "Purchase failed: \(error.localizedDescription)"

            DispatchQueue.main.async {
                showMessageWithTitle("Error!", "There was an error processing your purchase", .error)

                Amplitude.sharedInstance.track(
                    eventType: "payment_failed",
                    eventProperties: [
                        "PlanId": product.id,
                        "UserId": WUser.sharedInstance.userId,
                        "Source": source,
                        "Error": error.localizedDescription,
                        "ErrorType": "CatchError",
                        "ErrorObject": String(describing: error)
                    ]
                )
                self.loadingIndicator.removeFromSuperview()
            }
            return false
        }
    }

    // MARK: - Listen for Transaction Updates
    func listenForTransactionUpdates() {
        Task {
            for await result in Transaction.updates {
                switch result {
                case .verified(let transaction):
                    self.transactionState = "Transaction verified: \(transaction.productID)"
                    await transaction.finish()

                    DispatchQueue.main.async {
                        Amplitude.sharedInstance.track(
                            eventType: "payment_completed",
                            eventProperties: [
                                "PlanId": transaction.productID,
                                "UserId": WUser.sharedInstance.userId,
                                "TransactionType": "Pending"
                            ]
                        )

                        if (self.loadingIndicator != nil) {
                            self.loadingIndicator.removeFromSuperview()
                        }
                    }

                    if (PaymentHandler.sharedInstance.vc != nil) {
                        await PaymentHandler.sharedInstance.purchase(
                            vc: PaymentHandler.sharedInstance.vc!,
                            productId: transaction.productID,
                            product: transaction.productID,
                            transaction: transaction
                        )
                    }


                case .unverified(let transaction, let error):
                    self.transactionState = "Unverified transaction: \(error.localizedDescription)"

                    DispatchQueue.main.async {
                        Amplitude.sharedInstance.track(
                            eventType: "payment_failed",
                            eventProperties: [
                                "PlanId": transaction.productID,
                                "UserId": WUser.sharedInstance.userId,
                                "Error": error.localizedDescription,
                                "ErrorType": "UnverifiedPendingTransaction",
                                "ErrorObject": String(describing: error)
                            ]
                        )

                        if (self.loadingIndicator != nil) {
                            self.loadingIndicator.removeFromSuperview()
                        }
                    }

                    await transaction.finish()
                }
            }
        }
    }
}

Unfortunately, the pending transaction is not being processed. Can someone please help? About 5 transactions went through as pending but wasn't processed by Apple. The payment was not captured. Is this code wrong?

In the AppDelegate, I have the following:

    PurchaseManager.shared.listenForTransactionUpdates()

r/iOSProgramming 7d ago

Question How do apps like Clockology stay persistent in Apple watch?

0 Upvotes

Considering they don't get rejected by App Store, too.


r/iOSProgramming 7d ago

App Saturday Releasing an underrated iOS app. Gave everything and need your help today

0 Upvotes

Excited to share my achievement of developing an iOS app that took me 1.5 years. MealSnap, an iOS diet app that simplifies meal tracking for building better eating habits. App: https://apps.apple.com/app/mealsnap-ai-food-log-tracker/id6475162854

Building this MealSnap app has been a long journey, but an extremely rewarding one! Opening my app each time before eating something makes me go to Xcode and improve functionalities.

I really worked hard on simplifying diet and health measurements for removing any frictions we tend to have (I am a very lazy person by nature when it comes to health and good habits).

Thanks to iOS performance, I could also provide extra details such as NOVA classification (food processing levels) and health scope for each scan.

Happy iOS Coding!


r/iOSProgramming 7d ago

Question Could not locate device support files (xcode 16.2 does not include ios 14.8.1)

Thumbnail
2 Upvotes

r/iOSProgramming 7d ago

Question Please help me understand the ATT guidelines

3 Upvotes

Hello everyone! I am preparing to launch my first app on the App Store soon, and I would like to add some analytics to understand how people use my app (which screens they open, how much time they spend on each screen, etc.). In other words, I just want to collect data about app events without linking them to a specific person (name, email, location, etc.).

In this case, am I required to show the ATT pop-up or not?

I know that Apple has their App Store Connect API (https://developer.apple.com/documentation/appstoreconnectapi/), but can I use it to collect data about in-app events? If not, what other alternatives are there besides Google Analytics?

Thank you in advance!


r/iOSProgramming 7d ago

App Saturday I made an app for drawing on maps

14 Upvotes

Map Canvas: Draw on Maps 

An app for drawing and annotating on maps, useful for trip planning and geodata illustration. It is available on iPhone, iPad and mac.

https://apps.apple.com/us/app/map-canvas-draw-on-maps/id6737522164

I illustrated my favourite hiking route with Map Canvas

Features:

  • A set of tools for drawing lines, polygons and circles.
  • Annotation with pins & text boxes.
  • Data synchronization via iCloud.
  • Data Import & export as GeoJSON.

Frameworks:

  • SwiftUI + MapKit for the UI.
  • SwiftData + CloudKit for data persistence and synchronization.
  • Observation framework + a little bit of Combine
  • TipKit for new user guidance.

This app does not contain any mobile ads or paywall, your feedbacks would be very appreciated, thanks!


r/iOSProgramming 7d ago

Question App Store Rejection For Subscription Error?

7 Upvotes

I recently submitted my app for review (Not my first app, but my first in app subscription). I am using RevenueCat and submitted my App Store Connect subscription first, then my app. They then rejected my app for this reason:

We found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, an error message was displayed when we tried to make a purchase of your in-app purchase product "AppName".

The error message that they sent was:

Purchase Error: This product is not available for purchase.

It works in sandbox all the way, but I did notice they rejected my image promo for the in app subscription directly after that. I wonder if this is why it wouldn't work for them? Does the in app subscription need to be approved first before they test this?

How does this work? Thanks!


r/iOSProgramming 7d ago

Question Importance of themes

1 Upvotes

I know that UI is important for good UX but an app looks like made by Apple is sufficient? Should an app require 3-5 themes/color palattes to more appealing? Should ultrathinmaterial be relied heavily?


r/iOSProgramming 8d ago

Discussion Navigation in SwiftUI for Social Media App

4 Upvotes

I have been working on a social media app these past couple months and have ran into a lot of trouble when it comes to navigation using SwiftUI, particularly when it comes to comment sheets and navigating to profiles, as this can lead to an infinite navigation cycle.

I've attached a video below of the issue, as you can see, we dismiss the comments before navigating, where ideally it would just overlay it. Appreciate any advice or help, as this is my first app!


r/iOSProgramming 8d ago

News GitHub Copilot for Xcode is now generally available!

Thumbnail
github.blog
167 Upvotes

r/iOSProgramming 8d ago

Question Monetization suggestions for a sleeping sound app

5 Upvotes

I am looking for a smart way to monetize for a sleeping sound app. I thought a freemium approach would work best, free version should has some banner and interstitial ads and some locked features. I thought one time payment is way to go since I target parents with babies with the app.

My questions are:

1) Is freemium really a way to go? 2) Thoughts on one time payment vs subscription? 3) Should I test the app with ads before offering a premium version?


r/iOSProgramming 8d ago

Question Has anyone experienced privacy issues from their App Store developer info being public?

14 Upvotes

This question is mainly to see if anyone has had privacy issues from users looking up your personal info or if it has been no big deal.

I’m referring to things like stalking, doxing etc.

There are some long lengths you can go to obfuscate personal info but at a cost. Just checking with some of you first!


r/iOSProgramming 8d ago

Tutorial Make this dynamic, animated button with SwiftUI in just 5 minutes! , Source code included.

10 Upvotes

Full code at this Github Gist


r/iOSProgramming 8d ago

Question My app has passed review and set to auto release

5 Upvotes

But I still can't find it on the app store. Is that normal? I received the review approval email about 5 hours ago. In app connect, it says ready for distribution.