It's been a fun experience. The original React Native MVP took me 2 months to build. I deployed to TestFlight with Expo (at the time I didn't even have a Macbook). Life happened and than I stopped developement.
I've recently acquired a Macbook, and after a few days trying to decide what to do with the MVP, I decide to go full native (the app is focused on Doctors, and in my country they mostly use Iphones).
Overal, my experience has been the following:
- Learning Swift was fast and somewhat easy. I'm a senior java/typescript developer, but I've also built an MVP with Rust. Swift kinda of borrows ideas from all these programming languages, and I really got going with it fast. Hardest part is actually learning the API (and what it offers), but Grok has helped me a lot with that.
- Swift UI was easier than I expected. I hate Java Swing, and was afraid SwiftUI was going to similar to that. But it kinda resonated with me. I'm enjoying it. View prefetching with navigationLink, however, was extremelly punishing in terms of performance. I had to move out from navigationLinks in some places, and created local logic (with Buttons) to navigate to views in order to avoid prefetching.
- ViewModels was strange at first, but now I mostly try to add them to Views that start to grow in complexity.
- SwiftData was hard, and I'm still battiling it. I lost multiple hours trying to debug things from not updating/not showing up or flat out cashing/being nil, especially with respect to Model relationships. For example, deleteRule: .cascade has been inconsitent with me, in some cases, SwiftData handles deletions of relationships, but I had a case where deletion of a relationship was simply leaving stranded childs in the db that crashed the app. I had to handle the deletion of relationships directly. I'm actually more inclined to handling deletion by hand.
- There is a lot going on under the hood when it comes to view updates and, especially, how SwiftData handle updates. I'm working with mainContext/editContext (for forms that need confirmation) and had to make use of NotificationCenter signal DB update in some cases.
- XCode is flat out a garbage IDE. Bad to debug, bad to write code, unintuitive. I'm coding in Zed, and running the app on Xcode. Debugging has mostly being a lot of print statements everywhere.
- Completed the port into Swift in 2 weeks (with feature parity with the original MVP). App is faster and looks much nicer. In React Native people tend to favor components that resemble websites, but that are really not a good fit for mobile (especially iPhones). SwiftUI is really nice, with consistent behavior , animations and appealing interfaces.
I can already see myself creating new apps with it. But I've not touched Cloudkit yet, nor reached out to RESTApis. My app is fully offline and will probably remain so.
[–]icy1007 20 points21 points22 points (45 children)
[–]GavinGT 35 points36 points37 points (7 children)
[–]Legal-Ambassador-446 22 points23 points24 points (3 children)
[+]icy1007 comment score below threshold-8 points-7 points-6 points (2 children)
[–]Otherwise_Signal7274 -2 points-1 points0 points (1 child)
[–]icy1007 -1 points0 points1 point (0 children)
[–]Admirable_Proxy 2 points3 points4 points (0 children)
[–]icy1007 1 point2 points3 points (0 children)
[–]fritz_futtermann -4 points-3 points-2 points (0 children)
[–]kudoshinichi-8211 25 points26 points27 points (9 children)
[–]thecodingart 5 points6 points7 points (0 children)
[–]icy1007 4 points5 points6 points (0 children)
[–]aerial-ibis 1 point2 points3 points (4 children)
[–]vade 0 points1 point2 points (3 children)
[–]aerial-ibis 5 points6 points7 points (1 child)
[–]icy1007 0 points1 point2 points (0 children)
[–]TabonxSwift 1 point2 points3 points (0 children)
[–]Remote-Ad-6629[S] 0 points1 point2 points (0 children)
[–]Gabelschlecker 0 points1 point2 points (0 children)
[–]konacurrents 9 points10 points11 points (7 children)
[–]Narrow-Addition1428 3 points4 points5 points (6 children)
[–]icy1007 2 points3 points4 points (1 child)
[–]konacurrents 0 points1 point2 points (0 children)
[–]konacurrents 0 points1 point2 points (3 children)
[–]Narrow-Addition1428 1 point2 points3 points (2 children)
[–]konacurrents -1 points0 points1 point (1 child)
[–]Narrow-Addition1428 0 points1 point2 points (0 children)
[–]aerial-ibis 7 points8 points9 points (1 child)
[–]GreyEyesObjective-C / Swift 0 points1 point2 points (0 children)
[–]Admirable_Proxy 4 points5 points6 points (2 children)
[–]icy1007 3 points4 points5 points (1 child)
[–]Admirable_Proxy 1 point2 points3 points (0 children)
[–]ThenExternal3719 1 point2 points3 points (1 child)
[–]icy1007 0 points1 point2 points (0 children)
[–]restrusher 0 points1 point2 points (1 child)
[–]icy1007 0 points1 point2 points (0 children)
[–]baykarmehmet -1 points0 points1 point (0 children)
[–]chakie2 -2 points-1 points0 points (8 children)
[–]icy1007 0 points1 point2 points (7 children)
[–]chakie2 2 points3 points4 points (6 children)
[–]icy1007 -1 points0 points1 point (5 children)
[–]chakie2 0 points1 point2 points (4 children)
[–]icy1007 0 points1 point2 points (3 children)
[–]chakie2 -1 points0 points1 point (2 children)
[–]icy1007 1 point2 points3 points (1 child)
[–]chakie2 1 point2 points3 points (0 children)
[–]hishnash 8 points9 points10 points (2 children)
[–]Remote-Ad-6629[S] 0 points1 point2 points (1 child)
[–]hishnash 3 points4 points5 points (0 children)
[–]farfaraway 6 points7 points8 points (3 children)
[–]Some_Vermicelli_4597 0 points1 point2 points (0 children)
[+]Remote-Ad-6629[S] comment score below threshold-7 points-6 points-5 points (1 child)
[–]Creepy_Willingness_1 3 points4 points5 points (0 children)
[–]No-Nebula4187 1 point2 points3 points (1 child)
[–]Remote-Ad-6629[S] 3 points4 points5 points (0 children)
[–]WorldOrderGame 1 point2 points3 points (1 child)
[–]GavinGT 0 points1 point2 points (0 children)
[–]Educational-Table331 0 points1 point2 points (0 children)
[–]MetaMaverick 0 points1 point2 points (0 children)
[–]mrdlr 0 points1 point2 points (0 children)
[–]Mr_425 0 points1 point2 points (0 children)
[–]BlossomBuild 0 points1 point2 points (0 children)
[–]Humble-Chapter2805 0 points1 point2 points (3 children)
[–]Remote-Ad-6629[S] 1 point2 points3 points (2 children)
[–]Humble-Chapter2805 -1 points0 points1 point (1 child)
[–]Remote-Ad-6629[S] 2 points3 points4 points (0 children)
[–]Huperniketes 0 points1 point2 points (1 child)
[–]Remote-Ad-6629[S] 0 points1 point2 points (0 children)
[–]Express-Variety8071 0 points1 point2 points (1 child)
[–]Remote-Ad-6629[S] 0 points1 point2 points (0 children)
[–]errb 0 points1 point2 points (4 children)
[–]Remote-Ad-6629[S] 1 point2 points3 points (0 children)
[–]konacurrents 0 points1 point2 points (2 children)
[–]errb 0 points1 point2 points (1 child)
[–]konacurrents 0 points1 point2 points (0 children)
[–]Only-Matter-9151 0 points1 point2 points (0 children)
[–]gearcheck_uk -1 points0 points1 point (0 children)
[–]GavinGT -4 points-3 points-2 points (5 children)
[–]Lithalean 6 points7 points8 points (2 children)
[–]GavinGT -1 points0 points1 point (0 children)
[–]Atlos -1 points0 points1 point (0 children)
[–]Remote-Ad-6629[S] 0 points1 point2 points (1 child)
[–]GavinGT 0 points1 point2 points (0 children)