Overview
Car Booking is a pair of iPhone apps for the Car Booking SaaS – Car Rental Management System website: a Driver app for drivers and a Customer app for renters. Rental company owners and staff keep using the website. The apps talk only to your website, so all data stays on your server.
What is in the package
| Folder / file | What it is |
|---|---|
driver_app/ | Flutter project of the Driver app (bundle id com.carbooking.driverApp), with its ios/ folder ready. |
customer_app/ | Flutter project of the Customer app (bundle id com.carbooking.customerApp), with its ios/ folder and tools/build_branded.py. |
docs/mobile-api.md | Reference of the website API the apps use (for developers who want to extend them). |
README.md | Short overview and quick start. |
documentation/ | This guide. |
Features
Driver app
| Area | What the driver can do |
|---|---|
| Sign in | Email and password of the driver account created on the website. Stays signed in (token kept in the phone's secure storage). |
| Home | Today's jobs, the week ahead, money earned and to be paid, and alerts. |
| Jobs | Jobs for the next days with call the customer and open in maps buttons. |
| Start and finish a rental | Odometer and fuel level at start and at return; the website closes the contract and works out late and extra-kilometre fees. |
| Photos | Pick-up, return and damage photos, uploaded to the booking (visible to the office and the customer). |
| Bookings | History of the driver's bookings with search and filters. |
| Rental agreements | Read the agreement and sign with a finger. |
| Expenses | Add an expense (fuel, parking, toll…) with a photo of the receipt. |
| Earnings | Commission per completed job and the payout history. |
| Notices & push | Office notices; push notification when a job is assigned or cancelled. |
Customer app
| Area | What the renter can do |
|---|---|
| Find a company | Search by name or city, scan the company's QR code, or type the company code. One app can serve many rental companies, or you can build an own-brand app for one company (see Own-brand customer app). |
| Sign in | Email code, password, or phone SMS code (each method can be switched on or off by the company). New customers are registered on first sign-in. |
| Search cars | Pick-up and return date and time, only the free cars with the trip price, sorting (price, seats, name), filters (type, gearbox, fuel) and saved favourites. |
| Car page | Photos, extras, pick-up and return places, promo or friend code, notes, price breakdown and the company's rules (online payment, approval, free cancellation). |
| Book and pay | Book, then pay on the company's secure payment page (Stripe, PayPal, Paystack, Flutterwave or Razorpay, whichever the company enabled). |
| My bookings | Upcoming, past and cancelled. Per booking: status, dates, places, extras, money (total, paid, to pay), "show at pick-up" card, pay, extend the rental, rate the rental, invoice (PDF), cancel inside the free window, car photos, deposit and driver details, report a problem, add to calendar. |
| Home dashboard | Current trip, countdown to the next trip, directions, amount to pay, book again and offers. |
| Profile | Edit details, My documents (photograph the licence and ID with expiry date), Rewards (loyalty points, history, friend code, current promo codes), switch company, delete my account. |
| Contact | Call, WhatsApp, email, or a message into the company's inbox; Ask our AI helper when the company has it switched on. |
| Notifications | Inbox (bell) that keeps every message, plus push notifications when a booking is confirmed or cancelled and a reminder the day before pick-up and return. |
| Comfort & security | Light, dark and automatic appearance; optional fingerprint / face / PIN lock. |
Not included
- Paying by card inside the app (payment opens the company's own secure page, so card data never passes through the app).
- Saved cards and in-app language packs.
Requirements
Your computer (to build the apps)
| What | Version / notes |
|---|---|
| Mac | Apple Silicon (M1 or newer) recommended; macOS version required by the current Xcode |
| Xcode | Latest version from the Mac App Store (App Store uploads require a recent Xcode / iOS SDK) |
| Flutter SDK | Latest stable release (3.27 or newer; tested with 3.47) |
| CocoaPods | Latest (brew install cocoapods) |
| Python 3 with Pillow | Only for the own-brand build script (pip3 install pillow) |
| Disk | About 30 GB free (Xcode is large) |
Phones that can run the apps
iPhone with iOS 15 or newer.
Accounts
| Account | Cost | Needed for |
|---|---|---|
| Apple ID | Free | Running on your own iPhone during development |
| Apple Developer Program | $99 per year | Push notifications, TestFlight, App Store |
| Firebase (Google) | Free (Spark plan is enough) | Push notifications |
Enrol as an Organization (needs a D-U-N-S number, the seller name shows your company) or as an Individual (shows your personal name).
Website
Car Booking SaaS v1.7 or newer on HTTPS — see Prepare the website.
Install Xcode & Flutter
- Xcode: install from the Mac App Store, open it once, accept the licence and let it install components. Then in Terminal:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer sudo xcodebuild -runFirstLaunch xcodebuild -downloadPlatform iOS - Homebrew and CocoaPods (Homebrew from brew.sh):
brew install cocoapods - Flutter: follow docs.flutter.dev/get-started/install/macos (iOS). Add Flutter's
binfolder to your PATH (e.g. in~/.zshrc). - Check:
It must show ticks for Flutter and Xcode. (Android Studio is not needed for iPhone.)flutter doctor
Prepare the website
Do this once on the website before building the apps.
- Website on HTTPS. Install Car Booking SaaS v1.7 or newer on your domain with an SSL certificate (Let's Encrypt is free).
Release builds of the apps refuse plain
http://. - Run the update. If you upgraded an existing website, make sure the database update ran (
php artisan migrate --force, or the website's update screen). It creates the tables for phones, notifications, customer sign-in codes and photos. - Find your API address. It is your website address followed by
/api/mobile/v1, for examplehttps://rent.yourdomain.com/api/mobile/v1. Test it in a browser:https://rent.yourdomain.com/api/mobile/v1/companies?q=ashould answer with JSON (a list of companies), and…/api/mobile/v1/company/demoshows one company's name, logo and colour. - Online booking for each company. The customer app needs the company's online booking switched on (owner → Online Booking). The
company code is the web address name of that page:
…/book/demomeans codedemo. Owners also find the code, a QR code and a "copy message" button under Mobile apps in their menu. - Customer sign-in. Customers receive a 6-digit code by email, so the company needs working email settings (Settings → Email). The owner can also allow password sign-in and SMS code sign-in (needs the owner's Twilio account). Each method can be switched on or off by the company.
- Driver accounts. Create each driver under Driver in the owner's menu. Drivers sign in to the app with that email and password. Set the commission rule on the driver's page to see earnings in the app.
- Store links (optional but recommended). After publishing, add the Google Play / App Store links as super admin → Mobile apps. They appear on every
company's public "Get our app" page (
/book/<code>/app) together with the QR code. - Cron job and queue. The website's cron (
php artisan schedule:runevery minute) sends the reminders (pick-up, return, payment). For push notifications keep a queue worker running (php artisan queue:work) or setQUEUE_CONNECTION=syncin.env. - Upload size. Photos are sent from the phone: set PHP
upload_max_filesizeandpost_max_sizeto at least10M.
Set up the projects
The ios/ folder of both apps is already included, with the permission texts, app name, icons and deployment target applied. There is no setup script.
- Unzip the package. It contains
driver_app,customer_appanddocs; put them in a path without spaces, for example~/projects/iphone_app. - Download the libraries for each app:
Flutter installs the iOS libraries (CocoaPods) the first time you run or build. If that step ever fails, runcd ~/projects/iphone_app/driver_app flutter pub get cd ../customer_app flutter pub getcd ios && pod install --repo-update. - Set your website address. Either edit
lib/config.dartin each app:
or leave the file as it is and addstatic const String apiBase = String.fromEnvironment( 'API_BASE', defaultValue: 'https://your-domain.com/api/mobile/v1', );--dart-define=API_BASE=https://your-domain.com/api/mobile/v1to everyflutter run/flutter buildcommand. - Choose your bundle identifier. The placeholders are
com.carbooking.driverAppandcom.carbooking.customerApp. Change them to your own (for examplecom.acmerentals.driver) in Xcode (next section) before you create the app in App Store Connect.The bundle ID cannot change after the app is created in App Store Connect. - Open the Xcode project — always the workspace:
open ios/Runner.xcworkspace
--dart-define=COMPANY=demo to the command, or use the build script
(Own-brand customer app).Xcode signing & capabilities
Do this once for each app. In Xcode select Runner (blue icon, left) → target Runner:
- Signing & Capabilities tab → tick Automatically manage signing → Team: your Apple Developer team (add your Apple ID in Xcode → Settings → Accounts if the list is empty).
- Bundle Identifier: set your own, e.g.
com.acmerentals.driver. It must be unique in the App Store. - Click + Capability → Push Notifications.
- Click + Capability → Background Modes → tick Remote notifications.
- General tab → Minimum Deployments: iOS 15.0. Display Name: your app name.
- Optional (saves a question at every upload): in
ios/Runner/Info.plistadd<key>ITSAppUsesNonExemptEncryption</key><false/>— the apps only use standard HTTPS encryption.
Run on an iPhone or simulator
Simulator
open -a Simulator
flutter run --dart-define=API_BASE=https://your-domain.com/api/mobile/v1
Your iPhone
- Connect the iPhone with a cable, unlock it and tap Trust.
- On the iPhone: Settings → Privacy & Security → Developer Mode → on (restart when asked).
- Run
flutter run(or press ▶ in Xcode with your iPhone selected). The first time, on the iPhone go to Settings → General → VPN & Device Management and trust your developer certificate.
Testing against a local website (http)
For quick tests against a website on your Mac (simulator only): flutter run --dart-define=API_BASE=http://localhost/car-booking-saas/main_file/api/mobile/v1.
iOS blocks plain http:// on real devices unless you add an App Transport Security exception — for real devices, test against an https website.
Which account to sign in with
| App | Sign in with |
|---|---|
| Driver | The email and password of a driver account created on the website (owner → Driver). |
| Customer | The company code of a company that has online booking switched on, then any email address: the 6-digit code arrives by email. New emails become customer accounts on first sign-in. |
Branding & customisation
Changes that need no new build (from the website)
| What | Where on the website |
|---|---|
| Company name, logo and colour shown in the customer app | Owner → Settings → General (company name, logo) and the website colour. The customer app follows them every time it opens. |
| Which sign-in methods customers get | Owner → Online Booking / Settings (email code, password, SMS code) |
| Whether the company is listed in the app's search | Owner → Mobile apps → "List my company in the app" |
| Store links, QR code and company code page | Super admin / Owner → Mobile apps |
| Which push messages are sent | Owner → Configuration → Email Notification (Push Enable column and "Phone app notifications") |
Changes in the code (then build again)
| What | How |
|---|---|
| App name under the icon | CFBundleDisplayName in ios/Runner/Info.plist (or Display Name in Xcode). Currently "Car Booking Driver App" and "Car Booking". |
| Website address | apiBase in lib/config.dart, or --dart-define=API_BASE=… when building. |
| Fixed company (customer app) | --dart-define=COMPANY=your-code when building: the company screen is skipped. |
| App icon | In Xcode open ios/Runner/Assets.xcassets → AppIcon and drop a 1024×1024 PNG (no transparency, no rounded corners) — or replace the images in that folder. For the customer app the own-brand script (below) makes every size from one logo. |
| Launch screen | ios/Runner/Assets.xcassets/LaunchImage.imageset and Base.lproj/LaunchScreen.storyboard. |
| Login logo | Replace assets/logo.png (login screen) and assets/mark.png (small mark). |
| Driver app colours | lib/theme.dart. |
| Texts / translation | Screen texts are in lib/screens/. Permission texts are in ios/Runner/Info.plist. |
Push notifications (Firebase + APNs)
Without this step the apps work and show updates in the inbox, but iPhones do not get notifications. Apple delivers iPhone notifications through APNs; Firebase connects your website to APNs. You need a Firebase project, one file in each app, and one file on the website server.
A. Apple: APNs key
- developer.apple.com → Certificates, IDs & Profiles → Keys → +.
- Name it (e.g. "Push"), tick Apple Push Notifications service (APNs) → Continue → Register.
- Download the
.p8file (you can download it only once) and note the Key ID and your Team ID (top right of the page). - Check Identifiers → your bundle ID has Push Notifications enabled (Xcode does this when you add the capability).
B. Firebase
- console.firebase.google.com → create a project, or use the one for your Android apps.
- Add app → iOS, once per app: Apple bundle ID exactly as in Xcode (e.g.
com.acmerentals.driver) → Register. - Download GoogleService-Info.plist, drag it into Xcode into the Runner folder (tick Copy items if needed and the Runner target). Do this for both apps, each with its own file.
- Project settings → Cloud Messaging → Apple app configuration → APNs Authentication Key → Upload: the
.p8file, Key ID and Team ID. - Project settings → Service accounts → Generate new private key (only once per project; skip if you did it for Android).
C. Website server
- Save the service account JSON on the website server outside the web folder and put its path in the website's
.env:
Keep the queue running (FCM_CREDENTIALS=/home/youruser/firebase-service-account.jsonphp artisan queue:work) or useQUEUE_CONNECTION=sync. - Rebuild the apps. On a real iPhone (the simulator has limited push support): sign in and tap Allow for notifications.
- Test: in the admin panel assign the driver a job; the phone should ring within a few seconds. For the customer app confirm a booking of that customer.
When users are notified
| Who | Event | Opens |
|---|---|---|
| Driver | New job assigned | The job |
| Driver | Job cancelled | The job |
| Customer | Booking confirmed by the company | The booking |
| Customer | Booking cancelled by the company | The booking |
| Customer | Reminder the day before pick-up and the day before return | The booking |
Every message to a customer is also saved in the in-app inbox (the bell), even when phone notifications are off. The company switches push messages on or off under Configuration → Email Notification.
Version numbers
The version of each app is in its pubspec.yaml:
version: 1.0.0+1
1.0.0→ CFBundleShortVersionString (the version users see).+1→ CFBundleVersion (build number). Every upload to App Store Connect needs a higher build number (for the same version) or a new version.
Create the app in App Store Connect
Do this once for each app (driver and customer).
- appstoreconnect.apple.com → Apps → + → New App.
- Platform iOS, name (max 30 characters, must be unique in the App Store), primary language, bundle ID (the one from Xcode), SKU (any internal code, e.g.
acme-customer-ios), access: Full.
Build & upload
Make sure the apps point to your https website, then in each app folder:
flutter clean
flutter pub get
flutter build ipa --release --dart-define=API_BASE=https://your-domain.com/api/mobile/v1
# file: build/ios/ipa/*.ipa (archive: build/ios/archive/Runner.xcarchive)
If you set the address in lib/config.dart, the --dart-define part can be left out.
Upload it with one of:
- Transporter app (free on the Mac App Store): drag the
.ipain → Deliver. - Xcode: open
build/ios/archive/Runner.xcarchive→ Organizer → Distribute App → App Store Connect → Upload. - Command line:
xcrun altool --upload-app --type ios -f build/ios/ipa/*.ipa --apiKey <key> --apiIssuer <issuer>
After 5–30 minutes the build appears in App Store Connect → your app → TestFlight.
Alternative: in Xcode choose Any iOS Device (arm64) → Product → Archive → Distribute App.
TestFlight (beta testing)
- App Store Connect → TestFlight → the build → answer Export compliance ("uses only standard encryption / exempt") if asked.
- Internal testing: add up to 100 people from your App Store Connect team — available at once.
- External testing: up to 10,000 testers by email or public link; the first build gets a short beta review (about a day). Add the demo login in "Test information".
- Testers install TestFlight from the App Store and open your invitation.
Publish on the App Store
1. App information & pricing
- Category: Travel or Business (customer), Business (driver); secondary optional
- Content rights: no third-party content
- Age rating: answer the questionnaire (all "None") → 4+
- Price: Free; choose countries
2. App Privacy
Privacy policy URL and the data types — see Privacy & data safety. Data is "linked to the user", "not used for tracking".
3. Version page
| Item | Requirement | Suggestion |
|---|---|---|
| Screenshots | iPhone 6.9" (1320×2868 or 1290×2796) required; 6.5" (1242×2688) if asked. 1–10 each. | Take them in the iPhone Pro Max simulator (⌘+S) |
| Promotional text | Max 170 characters | Can change any time without review |
| Description | Max 4000 characters | The features of the app from this guide |
| Keywords | Max 100 characters, comma separated | car rental,rent a car,booking,vehicle,driver,fleet,travel |
| Support URL | Required | Your website's contact page |
| Build | Select the uploaded build |
4. App Review information
- Sign-in required: for the driver app give a demo driver email and password; for the customer app give the company code, a test email and how the reviewer gets the sign-in code (use a demo company with password sign-in switched on and a customer that has a password, so the reviewer does not need your email inbox). The demo account must have data (bookings, jobs, photos).
- Notes (example): "Car Booking is used by drivers and renters of car rental companies. Driver accounts are created by the rental company on its website. Customers sign in with a one-time code or password; creating an account is part of the first sign-in. Payment opens the rental company's own secure payment page (a real-world service). Customers can delete their account in Profile → Delete my account."
- Contact name, phone and email.
5. Submit
Add for Review → Submit. Review usually takes 1–3 days. Choose automatic or manual release after approval. Afterwards add the App Store links on the website: super admin → Mobile apps.
Common rejection reasons and how to avoid them
| Guideline | What to do |
|---|---|
| 2.1 App completeness | Demo account works, website online, data present, no placeholder texts. |
| 5.1.1(v) Account deletion | The customer app has Profile → Delete my account; explain how drivers are removed (by the company) in the review notes. |
| 4.2 Minimum functionality | Describe the many features in the notes and screenshots. |
| 3.1.1 Payments | Car rental is a real-world service: paying on the company's payment page is allowed. Do not sell digital content. |
| 5.1.2 Data use | Privacy labels must match the app (no tracking). |
| 4.0 Design | Your own icon and name (not the default), screenshots from the real app. |
Updates
Raise the version/build in pubspec.yaml, build, upload, create a new version in App Store Connect, select the build, submit.
Building without a Mac
- Codemagic (codemagic.io): connect your Git repository, choose the Flutter workflow, add your App Store Connect API key, and it builds and uploads to TestFlight. Has a free monthly build allowance.
- Cloud Mac rental (MacinCloud, AWS EC2 Mac, …): use it like a normal Mac through remote desktop and follow this guide.
- Signing and capabilities can be set up on developer.apple.com in the browser.
Privacy & data safety
Both stores require a privacy policy URL and a description of the data the apps handle. Publish a privacy policy page on your website (the website's own privacy policy page can be used) and use these answers in App Store Connect → App Privacy:
| Data | Collected | Purpose | Notes |
|---|---|---|---|
| Name, email, phone number | Yes | Account management, app functionality | Entered by the company (drivers) or the customer |
| Driving licence / ID photos | Yes (optional, customer app) | App functionality | "My documents" so pick-up is faster |
| Photos of vehicles and receipts | Yes (optional, driver app) | App functionality | Pick-up, return and damage photos, expense receipts |
| Signature image | Yes (optional, driver app) | App functionality | Agreement signing |
| Messages | Yes | App functionality, customer support | Contact the company, report a problem, AI helper |
| Purchase / booking history | Yes | App functionality | Bookings, payments, loyalty points |
| Payment info | No (in the app) | — | Payment happens on the company's secure payment page |
| Device / push token | Yes | App functionality | To send notifications |
| Location | No | — | Directions open the phone's maps app |
| Analytics, ads, tracking | No | — | No analytics or advertising libraries |
- Data is encrypted in transit (HTTPS).
- Data is not sold or shared with third parties for advertising.
iPhone permissions used
| Permission | App | Text shown (Info.plist) |
|---|---|---|
Camera (NSCameraUsageDescription) | Driver | "Take photos of the vehicle at pick-up, return or when you find damage." |
Photo library (NSPhotoLibraryUsageDescription) | Driver | "Choose photos of the vehicle to attach to the job." |
| Camera | Customer | "Take a photo of your driving licence or ID to speed up pick-up." |
| Photo library | Customer | "Choose a photo of your driving licence or ID." |
Face ID (NSFaceIDUsageDescription) | Customer | "Unlock the app with Face ID." |
| Notifications | Both | Asked after sign-in (only when push is set up) |
Change the texts (for example to translate them) in ios/Runner/Info.plist of each app.
iPhone settings reference
What is already set in the ios/ folder of the apps, for reference or when you change something by hand.
ios/Runner/Info.plist
<key>CFBundleDisplayName</key> <string>Car Booking</string>
<key>NSCameraUsageDescription</key> <string>Take a photo of your driving licence or ID to speed up pick-up.</string>
<key>NSPhotoLibraryUsageDescription</key> <string>Choose a photo of your driving licence or ID.</string>
<key>NSFaceIDUsageDescription</key> <string>Unlock the app with Face ID.</string> <!-- customer app -->
<key>LSApplicationQueriesSchemes</key> <array> ... </array> <!-- customer app: opens tel:, mailto:, https: links -->
Capabilities you add in Xcode
- Push Notifications
- Background Modes → Remote notifications
Deployment target
iOS 15.0 (IPHONEOS_DEPLOYMENT_TARGET in the Xcode project).
Firebase
GoogleService-Info.plist in ios/Runner/ (added to the Runner target). Without it the app runs and push stays off.
Code structure
Both apps
| Path | Contents |
|---|---|
lib/main.dart | Start-up, theme, chooses the sign-in or the main screens |
lib/config.dart | Server address (API_BASE), fixed company (customer app), app version |
lib/api.dart | HTTP client: token, JSON, errors, uploads and downloads |
lib/push.dart | Firebase notifications: permission, registering the phone, opening the right screen |
lib/theme.dart | Colours and styles |
lib/format.dart | Money and date helpers |
test/ | Unit tests (flutter test) |
Driver app screens (lib/screens/)
login, home, dashboard, jobs, job_detail, agreements, expenses, earnings, more.
Customer app screens (lib/screens/)
company and scan_code (find a company), login, home, dashboard, cars, car_detail, bookings,
booking_detail, booking_photos, documents, rewards, profile, contact, assistant (AI helper), notifications,
switch_company. Extra files: app_lock.dart (fingerprint / face / PIN), favorites.dart, cars_filter.dart, settings.dart.
Libraries used: Driver — http, flutter_secure_storage, image_picker, url_launcher, intl, firebase_core, firebase_messaging. Customer — the same plus local_auth (app lock) and mobile_scanner (QR codes). No analytics or advertising libraries.
To add a screen: create it in lib/screens/, load data with the client in lib/api.dart, and add the endpoint on the website in routes/api.php
(every endpoint is described in docs/mobile-api.md).
Own-brand customer app
By default the customer app is one app for many companies: the renter finds a company by name, QR code or code. A rental company that wants its own app (its own name, icon and store listing, with no company search) can have a copy built just for it.
From the customer_app folder (needs Python 3 with Pillow: pip install pillow, and Flutter on the PATH for --build):
python3 tools/build_branded.py \
--company sunrentals \
--name "Sun Rentals" \
--logo logo.png \
--api https://your-domain.com/api/mobile/v1 \
--package com.sunrentals.app \
--build none
| Option | Meaning |
|---|---|
--company | The company code (the web address name, e.g. sunrentals for …/book/sunrentals). The app skips the company screen. |
--name | App name under the icon |
--logo | PNG with the company's logo or mark (transparent background is best). All app icons and the login logo are made from it. |
--api | Your platform's API address |
--package | Android application id and iPhone bundle id, e.g. com.sunrentals.app (letters, numbers and dots, at least three parts) |
--build | apk, appbundle or none (only create the project) |
--out | Folder for the result (default build_branded/) |
The result is a copy of the app in build_branded/<company>/. The original is never changed. A company can add its own store links under Mobile apps in its menu;
they replace the platform's links on that company's website.
Updating to a new version
When a new version of the apps is released:
- Back up your project folders (
driver_appandcustomer_app), especially yourios/edits (signing,GoogleService-Info.plist),lib/config.dartandassets/. - Update the website first if the release notes say the apps need a newer website version.
- Copy the new
lib/,pubspec.yaml,test/anddocs/over your project. Put your own values back intolib/config.dart(or keep using--dart-define=API_BASE=…, which needs no edit). - Run
flutter pub get. - Run
cd ios && pod installafter replacing the files. - Raise the version in
pubspec.yaml(see "Version numbers"), build and upload as usual.
Troubleshooting
| Problem | Solution |
|---|---|
flutter: command not found | Flutter's bin folder is not in PATH. Open a new Terminal after changing PATH; check with flutter --version. |
flutter doctor shows Xcode problems | Run the commands in Install Xcode & Flutter (xcode-select, runFirstLaunch, downloadPlatform) and accept the licence. |
CocoaPods errors (pod install fails) | cd ios && pod repo update && pod install --repo-update. On Apple Silicon use a native (arm64) Terminal and a current CocoaPods (brew upgrade cocoapods). |
| "No connection" / "Could not reach the server" on every screen | Wrong API_BASE, or the website is on http:// (iOS blocks it on real devices). Open …/api/mobile/v1/companies?q=a in Safari on the iPhone to check. |
| Customer app: "company not found" | Check the code (the last part of …/book/<code>) and that online booking is switched on for that company. |
| Customer app: the sign-in code never arrives | The company needs working email settings (and the email may be in spam). Allow password or SMS sign-in for the company, or check storage/logs/laravel.log. |
| Driver app: "sign in with a driver account" | The account is not a driver (owners, managers and admins use the website) or the password is wrong. |
| Xcode: "Signing for Runner requires a development team" | Select your Team under Signing & Capabilities. |
| Xcode: bundle identifier already in use | Choose another bundle identifier (it must be unique in the whole App Store). |
| Xcode: "Untrusted Developer" on the iPhone | Settings → General → VPN & Device Management → trust your certificate. |
| Upload rejected: "The bundle version must be higher" | Raise the +number in pubspec.yaml. |
| Upload rejected: missing purpose string | A permission text is missing in ios/Runner/Info.plist (see iPhone permissions used). |
| No push notifications | Are Push Notifications and Background Modes added in Xcode? Is GoogleService-Info.plist in the Runner target and the APNs key uploaded to Firebase? Is FCM_CREDENTIALS set in the website's .env and the queue running? Tested on a real iPhone? Is push switched on under Configuration → Email Notification? |
| Photos fail to upload | Raise PHP upload_max_filesize / post_max_size to 10M+ on the server. |
| Payment page does not open | Online payment must be enabled and configured for the company on the website (Settings → Payment). |
| Old logo/colours shown | Close and reopen the customer app; it refreshes the company branding on start. |
FAQ
Do I need one app per rental company?
No. One customer app serves all companies on your website: renters find the company by name, QR code or code. A company that wants its own listing can have an own-brand build (Own-brand customer app).
Can owners and staff use the apps?
Not in this version. Owners, managers and staff use the website, which is fully mobile friendly. The apps are for drivers and customers.
Where is the data stored?
Only on your website/server. The iPhone keeps the sign-in token (in the Keychain) and a few settings such as saved favourites.
Does the app work without the website?
No, every screen loads from your website's API.
Can I change the server address without a new build?
No, the address is built into the app (API_BASE). Company name, logo and colours are not built in: they come from the website.
How do payments work?
Pay now opens the company's secure payment page in the browser (Stripe, PayPal, Paystack, Flutterwave or Razorpay); card data never passes through the app. Apple allows this because car rental is a real-world service.
Can I publish the apps under my own name?
Yes — your bundle ID, app name, icon and Apple Developer account.
Do I need a Mac?
Yes, Apple requires a Mac with Xcode to build iPhone apps; see Building without a Mac for cloud options.
Can I give testers the app before it is on the App Store?
Yes: TestFlight.
Can customers delete their account?
Yes: Profile → Delete my account in the customer app.
Support & changelog
Before contacting support, please check the Troubleshooting section and run flutter doctor.
When you contact support, include:
- Your purchase code
- App version (
pubspec.yaml) and website version - Output of
flutter doctor -v - The exact error message or a screenshot
- What you did just before the problem
Support covers installation questions, bugs and help with the steps in this guide. Customisations (new features, design changes) are not included in support but can be ordered separately. Create a support ticket here.
Changelog
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | October 2026 | First release: driver app and customer app. Driver: jobs, start / finish with odometer and fuel, photos, agreements with signature, expenses with receipt, earnings, notices, push notifications. Customer: find a company, email / password / SMS sign-in, car search, booking and payment, my bookings, extend, rate, documents, rewards, messages, AI helper, notifications, app lock, own-brand build script. |