iPhone

Smart Tenant – iPhone App Documentation

App v1.0.0 · needs website v3.6+

Overview

Smart Tenant is the iPhone app for the Smart Tenant property management website. It gives tenants and maintainers (repair staff) everything they need on their phone, while property owners, managers and the owner keep using the website. The app talks only to your website, so all data stays on your server.

White labelYour name, icon, logo and colours. Logo, favicon, title and colours also change live from the website — no new build.
One app for every companyAfter sign-in the app switches to the tenant's company branding, so a single App Store listing serves all your owners.
Same rules as the websiteEvery action runs the website's own code: permissions, limits and notifications are identical.
Push notificationsThrough Firebase, configured on the website. Inbox with unread badge in the app.
SecureLogin token kept in the phone's secure storage; HTTPS only in release builds; 2-factor login supported.
Ready for App StoreStep-by-step build, signing and store submission in this guide.

What is in the package

Folder / fileWhat it is
lib/The app's source code (Flutter / Dart).
assets/logo.png (login screen) and icon.png (app icon).
setup.shOne command that creates the iPhone project folder with every setting already applied.
pubspec.yamlApp version and the list of libraries.
docs/API.mdReference of the website API the app uses (for developers who want to extend it).
documentation/This guide.
Required: the app needs the Smart Tenant website v3.6 or newer, installed on a domain with HTTPS (SSL certificate). The website is a separate product.

Features

Tenant features

AreaWhat the tenant can do
HomeNext payment and amount due (red when overdue) with Pay now; total paid this year; lease dates and rent (and any scheduled rent change); property, address, unit, rooms, household; security deposit; autopay status; open repairs; polls to answer; documents that expire soon; inspection report waiting for a signature; parking; upcoming events. Quick buttons: Report a problem, Ask the assistant, Visitor pass, Book a facility.
InvoicesOpen / paid / all invoices; invoice details with items, payments, credit notes; online payment (Stripe / Razorpay — opens the website's secure payment page); PDF receipts downloaded and opened on the phone. The invoice refreshes by itself after paying.
RepairsReport a problem with type, description, photo (camera or gallery) and preferred visit day and time slot; follow the status; see the assigned maintainer and "on the way" notice; message the maintainer and office; rate the job when it is completed.
AssistantChat assistant (AI when enabled on the website) that answers questions, can raise a repair request from the conversation, and shows replies from office staff.
Payment historyAll payments grouped by year with totals per year and receipt downloads.
Security depositAmount held, received, deducted, refunded, the unit's required deposit and every entry.
My documentsDocuments on file (ID, insurance, …) with type, expiry date and "expired" / "expires soon" labels; open the file.
InspectionsMove-in, move-out and routine inspection reports room by room with condition, notes and photos; sign the report in the app.
Utility readingsMeter readings for the unit: previous / current reading, usage, rate and amount.
Notice boardNotices from the property manager.
Facility bookingsBook shared facilities (hall, gym, …) by free time slot, see bookings and their approval, cancel.
Visitor passesCreate a pass with visitor name, date, phone, purpose and vehicle; share the pass code; cancel.
PollsVote in property polls and see results when the manager allows it.
AgreementsRead the lease agreement PDF and sign with a finger.
ProfileName, phone, change password, phone notifications on/off, test notification, sign out.

Maintainer features

AreaWhat the maintainer can do
HomeCounts (urgent, pending, in progress, completed this month, hours, new today); today's visits; earnings this month; work queue (most urgent first); preventive maintenance tasks; recent ratings and feedback.
ScheduleThe next 14 days by day (Today, Tomorrow, …): repair visits on the tenant's preferred day and time slot plus preventive tasks; jobs without a set day at the end.
JobsOpen / pending / in progress / completed jobs. Job details: problem, AI summary and priority, photos, address with Directions (maps app), tenant name and Call, earlier repairs at the same unit, messages.
Updates"I'm on my way" (the tenant gets a notification and SMS); change status; enter cost, hours worked and fixed date; add an after photo and an invoice file. Completing the job notifies the tenant.
AccountTrade, properties covered, jobs completed, total hours, total billed, rating, member since; profile, phone notifications, sign out.

Common to both

Owners and managers are directed to the website: the app is for tenants and maintainers.

Requirements

Your computer (to build the app)

Building an iPhone app requires a Mac (Apple's rule). No Mac? Use a cloud Mac (MacinCloud, AWS EC2 Mac) or a CI service such as Codemagic — see Building without a Mac.
WhatVersion / notes
MacApple Silicon (M1 or newer) recommended; macOS version required by the current Xcode
XcodeLatest version from the Mac App Store (App Store uploads require a recent Xcode / iOS SDK)
Flutter SDKLatest stable release (3.27 or newer; tested with 3.47)
CocoaPodsLatest (brew install cocoapods)
DiskAbout 30 GB free (Xcode is large)

Phones that can run the app

iPhone with iOS 15 or newer.

Accounts

AccountCostNeeded for
Apple IDFreeRunning on your own iPhone during development
Apple Developer Program$99 per yearPush 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

Smart Tenant v3.6 or newer on HTTPS — see Prepare the website.

Install Xcode & Flutter

  1. 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
  2. Homebrew and CocoaPods (Homebrew from brew.sh):
    brew install cocoapods
  3. Flutter: follow docs.flutter.dev/get-started/install/macos (iOS). Add Flutter's bin folder to your PATH (e.g. in ~/.zshrc).
  4. Check:
    flutter doctor
    It must show ticks for Flutter and Xcode. (Android Studio is not needed for iPhone.)

Prepare the website

Do this once on the website before building the app.

  1. Website on HTTPS. Install Smart Tenant v3.6+ on your domain with an SSL certificate (Let's Encrypt is free). Release builds of the app refuse plain http://.
  2. 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 and notifications.
  3. Find your API address. Sign in as the owner → Settings → Mobile App. The page shows the address the app needs, which is your website address followed by /api/v1, for example https://app.yourdomain.com/api/v1. Open https://app.yourdomain.com/api/v1/app-config in a browser: you should see JSON with your logo and colours.
  4. Branding. Settings → General (Application Name, logo, favicon) and the theme colour are used by the app's login screen. Each owner's own General settings and theme are used after their tenants sign in.
  5. Accounts to test with. Create (or use) one tenant account and one maintainer account on the website.
  6. Cron job. The website's cron (php artisan schedule:run every minute) sends the reminder notifications (rent due, lease and document expiry).
  7. Upload size. Photos are sent from the iPhone; set PHP upload_max_filesize and post_max_size to at least 10M.

Set up the project

  1. Unzip the package. It contains the iphone_app folder; put it in a path without spaces, for example ~/projects/iphone_app.
  2. Choose your bundle identifier prefix: your company's reversed domain, e.g. com.acmehomes. The app's bundle ID becomes com.acmehomes.smartTenant (you can change it in Xcode in the next steps).
    The bundle ID cannot change after the app is created in App Store Connect.
  3. Run the setup script in Terminal:
    cd ~/projects/iphone_app
    chmod +x setup.sh
    ./setup.sh com.acmehomes "Acme Homes"
    cd ios && pod install && cd ..
    It creates the ios/ folder and applies everything the app needs:
    • Camera and photo library permission texts
    • Background notifications
    • App name under the icon (CFBundleDisplayName)
    • App icon from assets/icon.png
    • Downloads the Flutter libraries
    You can run it again at any time; it never duplicates settings.
  4. Set your website address in lib/config/app_config.dart:
    static const String appName = 'Acme Homes';
    static const String apiBaseUrl = String.fromEnvironment('API_BASE_URL',
        defaultValue: 'https://app.yourdomain.com/api/v1');
    static const String websiteUrl = 'https://app.yourdomain.com';
  5. Open the Xcode project — always the workspace:
    open ios/Runner.xcworkspace

How the setup script works

The ios/ folder is not included in the package on purpose: every app needs its own permanent bundle ID, so the folder is created on your computer with yours. setup.sh does this in two steps.

Step 1 — Flutter creates the folder

The script runs Flutter's own command:

flutter create . --org com.acmehomes --project-name smart_tenant --platforms ios

This builds a standard ios/ folder from Flutter's official template with your ID (com.acmehomes.smartTenant). The app's code in lib/ is not touched.

Step 2 — the script adds this app's settings

Flutter's template is generic, so the script then edits the new files:

FileWhat is added
ios/Runner/Info.plistCamera and photo permission messages, background notifications, app name under the icon
All icon sizesGenerated from assets/icon.png (dart run flutter_launcher_icons)
LibrariesDownloaded with flutter pub get

Result

iphone_app/
  ios/      <- created, with com.acmehomes.smartTenant
  lib/      (unchanged)
  assets/
  ...

Every change is also listed in Manual iOS settings, for reference or to make them by hand.

Xcode signing & capabilities

In Xcode select Runner (blue icon, left) → target Runner:

  1. 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).
  2. Bundle Identifier: check it, e.g. com.acmehomes.smartTenant. It must be unique in the App Store.
  3. Click + Capability → Push Notifications.
  4. Click + Capability → Background Modes → tick Remote notifications.
  5. General tab → Minimum Deployments: iOS 15.0. Display Name: your app name.
  6. Optional (saves a question at every upload): in ios/Runner/Info.plist add <key>ITSAppUsesNonExemptEncryption</key><false/> — the app only uses standard HTTPS encryption.
Push Notifications needs a paid developer account. With a free Apple ID you can still run the app on your own iPhone without that capability (notifications will not work).

Run on an iPhone or simulator

Simulator

open -a Simulator
flutter run

Your iPhone

  1. Connect the iPhone with a cable, unlock it and tap Trust.
  2. On the iPhone: Settings → Privacy & Security → Developer Mode → on (restart when asked).
  3. 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_URL=http://localhost/smart-tenant/main_file/api/v1. iOS blocks plain http:// on real devices unless you add an App Transport Security exception — for real devices, test against an https website.

Sign in with the tenant or maintainer account you created on the website.

Branding & customisation

Changes that need no new build (from the website)

WhatWhere on the website
Logo and name on the login screenOwner → Settings → General (Application Name, Logo)
ColoursOwner → Settings → theme colour
Company logo, name, colours after sign-inEach owner → Settings → General / theme
Push notification setupOwner → Settings → Mobile App

The app checks for changes every time it opens. The look is remembered, so it opens correctly even offline.

Changes in the code (then build again)

WhatHow
App name under the iconSecond argument of setup.sh (run it again), e.g. ./setup.sh com.acmehomes "Acme Homes". Also set appName in lib/config/app_config.dart.
Website addressapiBaseUrl in lib/config/app_config.dart (or --dart-define=API_BASE_URL=… when building).
App iconReplace assets/icon.png (1024×1024 px, your mark on a solid background, no transparency). Then run dart run flutter_launcher_icons. For iPhone the icon must have no transparency (remove_alpha_ios: true is already set).
Fallback logoReplace assets/logo.png (used only before the website has answered once).
Fallback coloursbrandColor and brandDarkColor in lib/config/app_config.dart.
"Use the website" link on loginwebsiteUrl in lib/config/app_config.dart.
Texts / translationScreen texts are in lib/screens/. Search for the English text and replace it.

The settings file:

class AppConfig {
  static const String appName = 'Acme Homes';
  static const String apiBaseUrl = String.fromEnvironment('API_BASE_URL',
      defaultValue: 'https://app.yourdomain.com/api/v1');
  static const Color brandColor = Color(0xFF2CA58D);     // buttons, links
  static const Color brandDarkColor = Color(0xFF0A2342); // headings, accents
  static const String logoAsset = 'assets/logo.png';
  static const String websiteUrl = 'https://app.yourdomain.com';
}

Push notifications (Firebase + APNs)

Without this step the app works and shows updates in the bell inbox, but iPhones do not get notifications. Apple delivers iPhone notifications through APNs; Firebase connects your website to APNs. The Firebase app settings are pasted on the website: no Firebase file inside the app.

A. Apple: APNs key

  1. developer.apple.com → Certificates, IDs & Profiles → Keys → +.
  2. Name it (e.g. "Push"), tick Apple Push Notifications service (APNs) → Continue → Register.
  3. Download the .p8 file (you can download it only once) and note the Key ID and your Team ID (top right of the page).
  4. Check Identifiers → your bundle ID has Push Notifications enabled (Xcode does this when you add the capability).

B. Firebase

  1. console.firebase.google.com → create a project, or use the one for your Android app.
  2. Add app → iOS: Apple bundle ID exactly as in Xcode (e.g. com.acmehomes.smartTenant) → Register.
  3. Download GoogleService-Info.plist. Do not add it to Xcode; skip the remaining SDK steps.
  4. Project settings → Cloud Messaging → Apple app configuration → APNs Authentication Key → Upload: the .p8 file, Key ID and Team ID.
  5. Project settings → Service accounts → Generate new private key (only once per project; skip if you did it for Android).

C. Website

  1. As the owner: Settings → Mobile App. Open each file in a text editor and paste:
    • the service account key JSON → Firebase service account
    • the GoogleService-Info.plist content → iPhone app (GoogleService-Info.plist)
    Save. A tick appears for each part.
  2. On a real iPhone (the simulator has limited push support): close and reopen the app, sign in and tap Allow for notifications.
  3. Test: tenant More → Send a test notification (maintainer: Account).
Development builds (run from Xcode) and TestFlight/App Store builds both work with an APNs key (.p8) — no separate certificates needed.

When users are notified

WhoEventOpens
TenantNew invoice, rent reminderInvoices
TenantPayment received, rent paid automatically (autopay), automatic payment failed, refund or credit issuedInvoices
TenantRepair status changed, maintainer "on the way"Repairs
TenantReply from the office in the assistant chatAssistant
TenantVisitor has arrivedVisitor passes
TenantFacility booking approved / not approvedFacility bookings
TenantNew notice, new pollNotice board / Polls
TenantRental agreement ready to signAgreements
TenantInspection report ready to signInspections
TenantDocument expiring soon, lease ending soon, rent change noticeMy documents / Home
MaintainerNew job assignedJobs

Every notification is also saved in the in-app inbox (the bell), even when phone notifications are off. Each user can switch phone notifications off under More (tenant) or Account (maintainer).

Version numbers

The version is in pubspec.yaml:

version: 1.0.0+1

Create the app in App Store Connect

  1. appstoreconnect.apple.com → Apps → + → New App.
  2. 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-tenant-ios), access: Full.

Build & upload

Make sure apiBaseUrl points to your https website, then:

flutter clean
flutter pub get
cd ios && pod install && cd ..
flutter build ipa --release
# file: build/ios/ipa/*.ipa   (archive: build/ios/archive/Runner.xcarchive)

Upload it with one of:

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)

  1. App Store Connect → TestFlight → the build → answer Export compliance ("uses only standard encryption / exempt") if asked.
  2. Internal testing: add up to 100 people from your App Store Connect team — available at once.
  3. 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".
  4. Testers install TestFlight from the App Store and open your invitation.

Publish on the App Store

1. App information & pricing

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

ItemRequirementSuggestion
ScreenshotsiPhone 6.9" (1320×2868 or 1290×2796) required; 6.5" (1242×2688) if asked. 1–10 each.Take them in the iPhone 16/17 Pro Max simulator (⌘+S)
Promotional textMax 170 charactersCan change any time without review
DescriptionMax 4000 charactersTenant and maintainer features from this guide
KeywordsMax 100 characters, comma separatedrent,tenant,landlord,repairs,maintenance,property,lease
Support URLRequiredYour website's contact page
BuildSelect the uploaded build

4. App Review information

5. Submit

Add for Review → Submit. Review usually takes 1–3 days. Choose automatic or manual release after approval.

Common rejection reasons and how to avoid them

GuidelineWhat to do
2.1 App completenessDemo account works, website online, data present, no placeholder texts.
5.1.1(v) Account deletionExplain how users request deletion (see notes above) and put it in the privacy policy.
4.2 Minimum functionalityDescribe the many tenant and maintainer features in the notes and screenshots.
3.1.1 PaymentsRent is a physical service: paying on the website is allowed. Do not sell digital content.
5.1.2 Data usePrivacy labels must match the app (no tracking).
4.0 DesignYour 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

Privacy & data safety

Both stores require a privacy policy URL and a description of the data the app handles. Publish a privacy policy page on your website and use these answers in App Store Connect → App Privacy:

DataCollectedPurposeNotes
Name, email, phone numberYesAccount management, app functionalityEntered by the property manager or the user
PhotosYes (optional)App functionalityRepair photos, after photos
Signature imageYes (optional)App functionalityAgreement signing
MessagesYesApp functionality, customer supportRepair messages, assistant chat
Payment infoNo (in the app)—Payment happens on the website's payment page
Device / push tokenYesApp functionalityTo send notifications
LocationNo—Directions open the phone's maps app
Analytics, ads, trackingNo—No analytics or advertising libraries
Account deletion: the stores expect users to be able to request deletion of their account. Accounts in this app are created by the property manager, not by the user. State in your privacy policy and store review notes how users ask for deletion (email address of your support or of the property manager).

iPhone permissions used

PermissionText shown (Info.plist)
CameraTake photos of problems and finished repairs.
Photo libraryAttach photos of problems and finished repairs.
NotificationsAsked after sign-in

Change the texts in ios/Runner/Info.plist (e.g. to translate them).

Manual iOS settings

What setup.sh adds to ios/Runner/Info.plist:

<key>CFBundleDisplayName</key>
<string>Acme Homes</string>
<key>NSCameraUsageDescription</key>
<string>Take photos of problems and finished repairs.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Attach photos of problems and finished repairs.</string>
<key>UIBackgroundModes</key>
<array>
    <string>remote-notification</string>
</array>

Plus in Xcode: Push Notifications capability (creates Runner.entitlements with aps-environment) and the app icon (dart run flutter_launcher_icons).

Code structure

PathContents
lib/main.dartStart-up, theme, chooses login / tenant / maintainer screens
lib/config/app_config.dartWhite-label settings
lib/core/api_client.dartHTTP client: token, JSON, errors, downloads
lib/core/auth_store.dartSign-in state, restores the saved session
lib/core/branding.dartLogo, name and colours from the website
lib/core/push_service.dartFirebase notifications, unread badge, opening the right screen
lib/screens/tenant/, maintainer/, common/, auth/All screens
lib/widgets/Shared widgets
ios/Xcode project (created by setup.sh)
docs/API.mdEvery API endpoint with parameters and responses

Libraries used: dio, provider, flutter_secure_storage (Keychain), firebase_core, firebase_messaging, flutter_local_notifications, url_launcher, image_picker, path_provider, open_filex, signature, cached_network_image, flutter_launcher_icons.

Updating to a new version

When a new version of the app is released:

  1. Back up your project folder (especially ios/, lib/config/app_config.dart and assets/).
  2. Update the website first if the release notes say the app needs a newer website version.
  3. Replace lib/, pubspec.yaml, setup.sh, docs/ and documentation/ with the new files. Keep your own ios/ folder, your assets/ images and put your values back into lib/config/app_config.dart.
  4. Run ./setup.sh com.yourcompany "Your App Name" again (same values as before). It only adds missing settings and never changes your package name or signing.
  5. Raise the version in pubspec.yaml (see "Version numbers"), build and upload as usual.

After replacing files run cd ios && pod install.

Troubleshooting

ProblemSolution
pod install fails / "CocoaPods not installed"brew install cocoapods; then cd ios && pod repo update && pod install.
"…requires a higher minimum iOS deployment version"In ios/Podfile set platform :ios, '15.0' (uncomment the line), then pod install.
"No profiles for … were found" / signing errorsXcode → Signing & Capabilities: choose your Team, Automatically manage signing on; the bundle ID must be unique.
"Untrusted Developer" on the iPhoneSettings → General → VPN & Device Management → trust your certificate.
Build fails after Xcode updateflutter clean, delete ios/Pods and ios/Podfile.lock, flutter pub get, cd ios && pod install.
"No connection" on every screenWrong apiBaseUrl or the website is not on HTTPS (iOS blocks http). Open …/api/v1/app-config in Safari on the iPhone.
"The app is for tenants and maintainers"The account is an owner/manager/admin; use the website or a tenant/maintainer account.
No notificationsReal iPhone (not simulator)? Push Notifications + Background Modes capabilities added? APNs key uploaded to Firebase with correct Key ID/Team ID? Bundle ID in Firebase matches Xcode? Website Settings → Mobile App shows ticks? Notifications allowed in iPhone Settings? Use "Send a test notification".
Upload rejected: "Invalid Bundle / missing icon"Run dart run flutter_launcher_icons; icon must be 1024×1024 without transparency.
Upload: "The bundle version must be higher"Raise the +number in pubspec.yaml.
Missing compliance on every buildAdd ITSAppUsesNonExemptEncryption = NO to Info.plist (see Xcode section).
Photos fail to uploadRaise PHP upload_max_filesize / post_max_size to 10M+ on the server.

FAQ

Do I need one app per property owner?

No. One app serves all companies on your website; after sign-in it shows the tenant's company branding.

Can owners or managers use the app?

Not in this version. They are directed to the website, which is fully mobile friendly.

Where is the data stored?

Only on your website/server. The phone keeps the login token (in secure storage) and the last branding.

Does the app work without the website?

No, every screen loads from your website's API.

Can I change the API without a new build?

The website address is built into the app. Branding and push settings are not — they come from the website.

How do payments work?

Pay now opens the website's secure payment page (Stripe/Razorpay) in the browser; card data never passes through the app. This is allowed by both stores because rent is a real-world service.

Can I build the iPhone app on Windows?

Not directly. Use a cloud Mac or Codemagic (see Building without a Mac).

Can I publish under my own company?

Yes — your bundle ID, app name, icon and Apple Developer account (enrol as Organization to show your company name).

Do I need the Android version too?

No. This product covers the iPhone app; both use the same website.

Support & changelog

Before contacting support, please check the Troubleshooting section and run flutter doctor.

When you contact support, include:

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.

Changelog

VersionDateChanges
1.0.0October 2026First release: tenant and maintainer apps, online payments, repairs with photos, assistant, agreements and inspections signing, deposit, documents, utility readings, notices, polls, bookings, visitor passes, schedule, push notifications and inbox, dynamic branding.