It was 9am in Abu Dhabi, and my client—a small eco-store owner in Al Nahyan—wanted an iOS app for their plant delivery service. They didn’t have the budget for two separate teams, so I sold them on React Native and Expo. “It’ll save us time and money,” I said, probably oversimplifying. By the end of the project, I’d remember why I’m not in sales.
The Tech Stack
We used Expo SDK 54. Why not the latest? Their legacy Firebase integration for order tracking broke with newer versions, and I wasn’t rewriting that mess for a 5% performance bump. For the UI, we stuck to React Native core components—no crazy custom native modules. The client wanted something “clean, like Careem, but for plants.”
Building in Expo was a mixed bag. The dev server worked fine, but when I tried to generate iOS builds via eas.build, Apple’s Developer Portal decided to throw a tantrum. The error: “Invalid App ID”. No hint, no specific logs. Just a red error box and 45 minutes of my life gone. Pro tip: If you’re in the UAE, enable Arabic in your Apple account settings. Why? Because half the error messages switch to Arabic, and one of them actually explains the problem. Yeah.
Getting Real About App Store Requirements
Apple won’t let you upload builds unless your App Store metadata is 100% complete. That’s brutal when your client keeps changing the app description at 2am. They wanted screenshots in both English and Arabic, so I wrote a Python script to overlay localized text. It half-worked, but hey, it saved me from manually editing 200+ images in Figma.
A random Friday, my client asked, “What’s the word count for the app description?” I checked Apple’s guidelines. It’s 4,800 characters. Their draft? 7,000. We argued about trimming until I realized the Arabic version needed even more space because of longer words. Eventually, we hired a translator—worth every dirham. Apple’s rejection emails are exhausting.
The Android Wild Card
We shipped to Android first. That’s how I debug iOS stuff—test on Android, then see what breaks. Not ideal, but Expo’s dev client is smoother there. For iOS, we had to detach to the legacy bare workflow to fix a payment gateway module (don’t ask). The build size jumped by 20MB overnight.
At one point, the splash screen started flashing green then white before launching. Turns out, the brandColors.json file in Expo’s expo-splash-screen package had a hex code typo. It took me 3 hours to find because I assumed the issue was in the native iOS config. Never assume.
Deployment: UAE Market Realities
This app had to work in both English and Arabic. We made the default language match the user’s device settings. For data, we switched from Firebase to a Laravel API because the client wanted more control over their inventory. Firebase’s realtime updates were overkill anyway—plant stock doesn’t change by the second.
I used React Query for caching. On 4G, the average load time dropped from 3.2s to 1.1s in Abu Dhabi and Dubai. Not bad for a $5K project.
One Weird Push Notification Glitch
Push notifications worked fine on Android. iOS? Silent failures. I checked APNs certs—good. Checked the device tokens—correct. Finally, I realized the client had typed the P8 auth key with “1” instead of “l” in one spot. We both missed it because Arabic keyboards default to a different layout. The typo was invisible in the Apple portal’s font. Fixed that, and boom: alerts started landing.
After Launch: The Numbers
3 weeks in, 40% of users opened the app daily. The client ran a promo in local eco-groups—worked well. Most iOS users came from WhatsApp links, not the App Store. Interesting.
Should I use Expo for another iOS project in the UAE? Honestly, only if the client needs speed. For more complex apps, I’d go full native. Expo’s a savior for prototyping, but Apple’s hoops and localization quirks will beat you up.
I’m Sarah, a freelance developer who ships apps for UAE and GCC businesses. If you’re curious about Greeny Corner (that plant app we launched) or want to chat about React Native gotchas, hit me up at sarahprofile.com/contact.