agentleFS
SajidisrarSajidisrar/ios-claude-skills/skills/ios-port-from-android/SKILL.md

ios-port-from-android

Skill1 starsChanged 15 days agoMITView on GitHub

Port an existing Android app (Kotlin/Jetpack Compose/Views) to a native iOS app (Swift/SwiftUI) — inventory the Android app, map each feature and Google/Android service to its iOS equivalent, flag what has no direct equivalent or is restricted by App Review, and rebuild in vertical slices with a parity checklist. Use when asked to bring an Android app to iOS, estimate an iOS port, or find the iOS equivalent of an Android API or pattern.

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 3 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Ask, and record the answer in the project's decision log:

    line 16
  2. Distinctive:

    Use this as the starting point and check each row against Apple's documentation (developer.apple.com) before relying on it.

    line 41
  3. Distinctive:

    Keep the backend contract unchanged.

    line 84

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Port an Android app to iOS

A port is a re-implementation of behaviour, not a translation of code. Match what the user can do and what the app guarantees (offline behaviour, security, data model); let the UI follow Apple's Human Interface Guidelines rather than copying Material layouts.

Direction matters: the mirror skill ios-port-to-android covers iOS → Android.

0. Decide the approach first

Ask, and record the answer in the project's decision log:

  • Native Swift/SwiftUI rewrite (this skill's default).
  • Share code — e.g. Kotlin Multiplatform for domain/data layers consumed from Swift. If the team wants this, the port plan changes (shared modules first); confirm before starting.
  • iOS deployment target, devices (iPhone only? iPad?), and whether the Android app keeps evolving during the port (if so, freeze a reference commit).

Then apply the project's other skills as normal: ios-feature-module for each feature, ios-swiftui-screen for screens, ios-unit-tests for tests.

1. Inventory the Android app

Produce a table before writing any Swift. One row per item:

  • Screens and flows — every screen/destination, its states, how you reach it (bottom nav, navigation graph, dialog, deep link), and what the system back button does.
  • Platform services — every permission in AndroidManifest.xml, services, broadcast receivers, WorkManager jobs, widgets, intent filters, content providers.
  • Third-party SDKs — and whether each has an iOS SDK (Swift Package preferred).
  • Backend contract — endpoints, auth flow, push payloads. Keep the API the same; differences found here are backend items, not iOS workarounds.
  • Data at rest — Room, DataStore/SharedPreferences, files, Keystore-protected data.

2. Map each item

Use this as the starting point and check each row against Apple's documentation (developer.apple.com) before relying on it.

AndroidiOSWatch out for
Jetpack Compose / ViewsSwiftUI / UIKitRespect the project's deployment target when picking APIs
Navigation Compose, bottom nav, dialogsNavigationStack, TabView, sheets/alertsNo system back button: every pushed screen needs swipe-back and a visible way out
ViewModel + StateFlow@Observable (iOS 17+) or ObservableObject view modelPick the observation model the deployment target allows
Coroutines, viewModelScope, dispatchersasync/await, Task, actors, @MainActorCancel work in .task {} rather than tying it to a scope object
Kotlin FlowAsyncSequence / AsyncStream, or Combine where the project uses it—
Retrofit/OkHttp/Ktor + serializationURLSession + CodableKeep the same JSON field names and error shapes
RoomSwiftData (iOS 17+) or Core DataPlan schema versioning from v1
DataStore / SharedPreferencesUserDefaults (non-sensitive only)—
Keystore / encrypted storageKeychainChoose the accessibility class deliberately
WorkManagerBackgroundTasks (BGAppRefreshTask, BGProcessingTask)iOS schedules at its discretion; long-running background services are not allowed — redesign them
Foreground servicesNo general equivalentOnly specific background modes exist (audio, location, VoIP…); each needs justification at review
FCMAPNs (FCM can relay to APNs)Request notification permission in context
Google Play BillingStoreKit 2Digital goods generally must use In-App Purchase — check App Review guideline 3.1
Android App Links / assetlinks.jsonUniversal Links / apple-app-site-associationNeeds the Associated Domains entitlement
App Widgets / GlanceWidgetKitWidgets are timeline-based and not interactive beyond App Intents buttons/toggles
Ongoing/progress notificationsLive Activities (ActivityKit)—
Intents to other apps, share sheetShareLink / UIActivityViewController, URL schemesMuch less inter-app access than Android; check each case
Google Sign-In / Credential ManagerSign in with Apple, AuthenticationServicesThird-party login may require offering Sign in with Apple or an equivalent — check guideline 4.8
Manifest permissions + runtime requestsInfo.plist usage strings + system promptsMissing usage string = crash on access
Play Data safety formPrivacy manifest + App Privacy labelsSee ios-privacy-compliance
strings.xml, pluralsString Catalogs—
sp scaling, TalkBack, semanticsDynamic Type, VoiceOver, accessibility modifiersSee ios-accessibility-audit
JUnit, Compose UI testsSwift Testing / XCTest, XCUITestPort the test cases, not the test code
GradleSwift Package Manager / Xcode project—
Material Symbols, RobotoSF Symbols, system fontUse the platform's own; don't ship Material's look as-is

Anything without a clear equivalent — or that App Review would reject — goes on a gap list with a proposed alternative and an owner (design, product or backend). Don't silently drop a feature.

3. Build in vertical slices

  1. Foundation: project setup, composition root, networking client, auth/session, error model, design tokens.
  2. Then one feature at a time, end to end (data → view model → screen → tests), in the order users need them — usually sign-in, then the main list/detail.
  3. For each slice, port the Android tests' cases as Swift tests first, so behaviour parity is checked, not assumed.
  4. Keep the backend contract unchanged. If iOS needs something the API lacks, raise it.

4. Parity check

Per feature, compare against the Android reference build: same data, same states, same errors, same offline behaviour, same analytics events (if any). Record each as matches, differs by design (iOS convention — say which), or gap.

Verification

  • The approach (native vs shared code), deployment target and Android reference commit are recorded.
  • Inventory covers every screen, manifest permission, service, receiver, widget and SDK.
  • Every mapping used was checked against Apple's documentation.
  • Background work and foreground services were redesigned for iOS limits, not ported literally.
  • Payment and sign-in choices were checked against the current App Review Guidelines.
  • Every item without an equivalent is on the gap list with an owner; none was dropped.
  • Every pushed screen can be dismissed without a system back button.
  • Each feature has a parity verdict, and the Android test cases exist as Swift tests.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.