Skip to content

KMP iOS Migration: commons module — approach discussion #2238

@mstrofnone

Description

@mstrofnone

Summary

This is the tracking issue for making Amethyst's commons module compile for iOS (iosArm64 + iosSimulatorArm64) via Kotlin Multiplatform. The approach: no iosApp module yet, small incremental PRs, move code from amethyst/commons/ piece by piece, maintain backward compatibility via typealiases at original locations.

159 PRs open, all passing CI, all mergeable. 28 PRs created in session 5. Only #2201 (LargeCache fix) has been merged so far. Zero reviews on the iOS migration PRs. More PRs being created now.


Phase-by-Phase Breakdown

Phase 1: KMP Foundation (6 PRs)

PR What Why
#2212 expect/actual for ConcurrentHashMap, AtomicBoolean, ReentrantLock K/N needs native equivalents
#2213 expect/actual for java.net.URI, java.io.* JVM stdlib unavailable on iOS
#2214 iOS compilation targets (iosArm64 + iosSimulatorArm64) The "make it compile" change
#2217 iOS WebSocket via NSURLSessionWebSocketTask Relay connections
#2221 Coil 3 via Ktor Darwin engine Image loading
#2240 Fix suspend calls in MarmotSubscriptionManagerTest K/N test fix

Phase 2: Model & Architecture — IAccount (21 PRs)

PR What
#2215 Move 120+ model/state files
#2216 IAccount + ICacheProvider interfaces; move Account.kt
#2218-#2220 Feed flows, GeoHash, FeedTopNavFilterState
#2236 IAccountViewModel, Route, INav, EmptyNav
#2237 IAccount +9 members, +26 drawables
#2257 IAccountViewModel 40+ members
#2259 IToastManager (7 methods)
#2260 IAccount +10 (bookmarkState, isFollowing, etc.)
#2261 Wire IToastManager → IAccountViewModel
#2267 IUiSettingsState + IAccountViewModel expanded
#2278 IAccount v3 (+10 domain methods)
#2280 IAccount v4 (+10 relay/visibility/follow)
#2289 IAccount v5 (+15 bookmark/payment/zap)
#2304 IAccount v6 (+15 reactive StateFlow properties)
#2313 IAccount v7 (+7 chat/relay/hidden)
#2318 IAccount v8 (+10 members, 9 new interfaces: blossom, relay lists, people/follow/bookmark lists, cache, settings, hiddenUsers)
#2325 IAccount +bookmarkState, oldBookmarkState, transientHiddenUsers, cacheProvider
#2356 IAccount v9 +15 members (allFollows, trustedRelays, pinState, hiddenUsers) + IAccountViewModel +18 members (launchSigner, nip05ClientBuilder, decrypt, follow/unfollow) + 5 new interfaces
#2293 31 non-inline signer wrappers
#2299 10 launchSigner call sites migrated

Phase 3: IAccountViewModel Signatures (16 PRs — COMPLETE, ~700+ signatures across ~360 files)

PR Signatures Key items
#2262 6 First batch
#2275 23 Second batch
#2287 27 v2 (22 files)
#2298 30 v3
#2309 23 v4
#2323 24 v5: note elements, NIP-22, profile tabs, buttons, chat actions
#2330 24 v6: LoadNote, LoadUser, LoadDecryptedContent, LoadAddressableNote loaders
#2345 22 v7: IAccountViewModel + IToastManager + IUiSettings expanded, 25 composable sigs
#2346 63 v8: note/types A-L (23 files) — shadow cast scaffolding pattern
#2348 12 v10: note/ non-types (11 files) + IAccountViewModel/IUiSettings/IToastManager infra
#2349 66 v9: note/types M-Z (29 files) — completes all note/types/
#2350 VM batch 10: 7 ViewModels + PeopleList data class moved to commons
#2351 39 v13: profile/ (39 files)
#2352 112 files v11: 17 screen/loggedIn subdirs (threadview→home)
#2353 73 files v12: chats/ — largest directory
#2354 44 files v15: navigation, feeds, components, actions, call, broadcast
#2355 28 files v14: relays/

Phase 4: Platform Abstraction Interfaces (5 PRs)

PR What
#2283 IMediaUploader interface
#2288 IHttpClientBuilder (8 methods)
#2295 AndroidMediaUploader + 3 metadata VMs
#2297 ChannelMetadata + NewUserMetadata VMs
#2310 10 expect/actual wrappers — ALL java.* gone from commonMain

Phase 5: Theme & Resources (6 PRs)

#2222 (Color/Shape/Type), #2223 (PubKeyFormatter), #2224 (1,978 strings + 77 translations), #2244 (complete Shape + ThemeExt), #2246 (StringResolver), #2256 (markdownStyle + chartStyle)

Phase 6: Platform Interfaces (2 PRs)

#2245 (IPlatformClipboard/Share/Toast + 199 R.string), #2251 (Android implementations)

Phase 7: R.string Migration (10 PRs, 900+ files)

#2225-#2229 (311 files), #2252 (Context→StringResolver, 229 calls), #2258 (Int→StringResource, 10 types), #2264 (toast classes), #2272 (55 legacy callers — completes toast)

Phase 8: R.drawable Migration (4 PRs)

#2241 (23 drawables), #2243 (25 final), #2250 (42 code refs), #2254 (15 Int→DrawableResource)

Phase 9: Composable & File Moves (24 PRs, 440+ files)

PR What Files
#2230-#2235 Batches 1-5 194
#2242 Batch 5v2 40
#2248-#2249 Resolved deps + Icons 7
#2255 Batch 6 36
#2263 Batch 7 5
#2265 IAccountViewModel composables + INav 4
#2268 Hashtag/Geohash/Chess filter chains 12
#2273 Filters + toast types + interfaces 9
#2282 Batch 8 15
#2286 VoicePreset + TorSettings (batch 9) 2
#2300 Batch 10 20
#2302 SetUtils + IsLiveStreaming 2
#2316 Batch 11 18
#2322 Batch 12: GlowingCard, LoadingAnimation, ClickableTexts, layouts, feeds, DraggableRelayList 14
#2328 Batch 13: ServerName, StringFeedState, BookmarkType, SupportedContent, AdditiveComplexFeedFilter 6
#2338 Batch 14: ChannelFeedState, SplitBuilder, ForwardingPainter, ToastMsg family, IExpiration, IZapRaiser, GenericLoadable, UrlPreviewState, TranslationConfig 14

Phase 10: Sealed Class & Data Class Moves (8 PRs, 13+ groups)

PR What
#2284 GenericLoadable + UrlPreviewState + 26 consumers
#2290 BookmarkType, IExpiration, IZapRaiser, AdditiveComplexFeedFilter
#2291 TranslationConfig + smart cast fixes
#2292 TorServiceStatus + data objects
#2296 ChannelFeedState, StringFeedState, UserFeedState
#2279 Route + kotlinx-serialization
#2300 20 files: sealed classes, toast family, utilities
#2327 CashuToken+Proof, SendState+ReceiveState, WritingAssistant, NamecoinResolveState, ConnectivityStatus, RelayResult+BroadcastStatus

Phase 11: DAL Filter Infrastructure (10 PRs)

PR What
#2301 AdditiveComplexFeedFilter + DefaultFeedOrder comparators
#2303 IHiddenUsersState + IBlockPeopleListState
#2305 IFeedTopNavFilter + marker interfaces
#2306 IAccountSettings + TopFilter sealed class
#2307 PinListState + bookmark/pin on IAccount
#2308 IRelayListState for proxy/blocked
#2312 ICacheProvider notes/addressables accessors
#2324 ICacheProvider v2: 5 collection properties as ICacheOperations, 6 lookups, 3 searches
#2326 FilterByListParams → commons with IFilterByListTopNavFilter
#2332 IFollowListFilter + FeedType enum + filterNotes/filterAddressablesByKind + feedFollowListFilter on IAccount

Phase 12: DAL Filter Moves (10+ PRs, 35 filters moved, more in progress)

PR Filters What
#2311 8 Batch 1
#2314 LargeSoftCache extensions
#2315 GlobalTopNavFilter + 9 relay impls
#2319 4 Channel, Community(x2), Draft (batch 3)
#2325 5 BookmarkPrivate/Public, OldBookmark, Spammer (batch 4)
#2329 6 GeoHash, Hashtag, Community(x2), UserProfileConversations, UserProfileNewThread (batch 7)
#2331 4 HiddenAccounts, HiddenWords, FollowPackMembers, PinnedNotes (batch 6)
#2332 8 Picture, DiscoverFollowSets, DiscoverLongForm, Polls, DiscoverMarketplace, Chess, ClosedPolls, OpenPolls (batch 5)

Phase 13: Navigation (2 PRs)

#2266 (KMP nav dep), #2271 (NavigationEffects)

Phase 14: ViewModel Migration (8 PRs)

#2247 (TorDialogVM), #2253 (UserFeedVM+StringFeedVM), #2274 (RelayFeedVM+NewEphemeralChatMetaVM), #2281 (UserExternalIdentitiesVM), #2317 (ThreadFeedVM+ChannelFeedVM), #2320 (UserProfilePinnedNotes+Bookmarks+Channel VMs), #2347 (relay VM infra — BasicRelaySetupInfoState + 6 commons files), #2350 (7 VMs: Zap/Bounty/Poll/Reaction/PeopleList/FollowPack), #2356 (IAccount v9 + IAccountViewModel expansion + 5 interfaces + RelayListCard)

Phase 15: launchSigner Migration (4 PRs, 87 call sites — COMPLETE)

#2299 (10 sites, batch 1), #2321 (14 sites + 12 VM wrappers, batch 2), #2333 (~49 sites + 17 VM wrappers, batch 3), #2340 (14 sites, batch 4 — final)

Phase 16: Infrastructure Cleanup (2 PRs)

#2276 (12 SubAssemblers → PerKeyEoseManager), #2277 (remove stale wrappers)

Phase 16b: Session 4 DAL Filters & Infrastructure (12 PRs)

PR What
#2334 Relay, Mutual, AppRecommendations, WebBookmark filters (batch 9)
#2335 Notification, FollowPack, Gallery, Shorts, Longs filters (batch 8)
#2336 Home, Video, DiscoverCommunity, DiscoverNIP89 filters (batch 7)
#2337 ChatroomListKnown, ChatroomListNew filters
#2339 DiscoverChat, DiscoverLive, ParticipantListBuilder, IOnlineChecker (batch 10)
#2341 UserFeedVM + StringFeedVM base classes
#2342 GenericLoadable, UrlPreviewState, ConnectivityStatus sealed classes (batch 3)
#2343 15 filter functions + SingleSubNoEoseCacheEoseManager
#2344 12 composables (batch 15)
#2345 IAccountViewModel v7 (22 new members + 25 signatures)

Other

#1914 (Desktop Namecoin NIP-05)


Architecture Decisions

  • Typealias backward compat — moved files get typealias at original location, zero breakage
  • 20+ abstraction interfaces — IAccount (140+), ICacheProvider, IAccountViewModel, IToastManager, IUiSettingsState, INav, IMediaUploader, IHttpClientBuilder, IAccountSettings, IHiddenUsersState, IBlockPeopleListState, IRelayListState, ITopNavFilter, IHiddenUsersFlow, IBlossomServerListState, INip65RelayListState, ISearchRelayListState, IPeopleListsState, IFollowListsState, ILabeledBookmarkListsState, ILocalRelayListState, IFilterByListTopNavFilter, IFollowListFilter
  • Sealed classes = direct imports — typealiases break is checks
  • viewModelScope bridgeaccountViewModelScope
  • launchSigner → 31+ suspend wrappers + 12 VM wrappers
  • expect/actual — ALL java.* removed from commonMain
  • ICacheOperations — collection-level filterIntoSet/forEach on notes, addressables, users, channels
  • FilterByListParams in commons with IFollowListFilter abstraction

Current State

Complete (131 PRs, session 5 in progress):

  • All R.drawable + R.string migration
  • Complete theme + platform interfaces + StringResolver + AndroidMediaUploader
  • IAccount (140+ members, 8 expansions, 31 signer wrappers, 15 reactive flows, 9+ relay/list interfaces)
  • ICacheProvider (5 collections as ICacheOperations, 6+ lookups, 3+ searches, filter helpers)
  • FilterByListParams + IFollowListFilter + FeedType in commons
  • 560+ composables/files moved
  • 19+ sealed class groups moved
  • ~700+ composable signatures → IAccountViewModel (16 PRs — COMPLETE, ~360 files)
  • 87 launchSigner call sites migrated + 72 wrappers (COMPLETE)
  • 43+ ViewModels/state classes migrated
  • 78+ DAL FeedFilter subclasses moved (16+ PRs)
  • 10 expect/actual JVM wrappers
  • Navigation, Route, SubAssemblers, cleanup

🔄 Session 5 — 22 PRs done (#2346-#2367), 3 running:

Signature migration COMPLETE (8 PRs, ~360 files):
#2346 (v8, note/types A-L), #2349 (v9, note/types M-Z), #2348 (v10, note/ non-types), #2352 (v11, 17 screen dirs, 112 files), #2351 (v13, profile/), #2353 (v12, chats/, 73 files), #2355 (v14, relays/), #2354 (v15, nav/feeds/components)

ViewModel migration (7 PRs):
#2347 (relay VM infra), #2350 (7 simple VMs), #2360 (5 posting state classes), #2365 (community filters), #2366 (SearchBarState), #2367 (5 filter+VM pairs: GeoHash, Hashtag, Relay, UserProfile), #2368 (NIP-86 RelayManagementState), #2369 (wallet/payment state: ZapFormatter, WalletState, NwcWalletEntry, ZapPollValidation), #2370 (notification/settings: StringFeedState, NotificationKinds, CountFormatter)

Interface expansion (3 PRs):
#2356 (IAccount v9 +15, IAccountViewModel +18, 5 interfaces), #2361 (IAccount +bookmarkState/pinState/hiddenUsers, 12 FeedFilters), #2364 (ICacheProvider v3: notes/addressables as ICacheOperations, filterIntoSet extensions)

Composable/file moves (4 PRs):
#2357 (batch 16, 9 files), #2358 (batch 17, 3 note/types), #2359 (batch 18, 4 elements), #2363 (batch 19, 6 screen files)

Infrastructure (2 PRs):
#2362 (shadow cast removal, 41 casts from 11 files), #2367 (ICacheProvider filterNotes/filterAddressableNotes + IAccount.liveHiddenUsers)

All session 5 agents complete (28 PRs). Wave 3 added: FilterByListParams (#2371), 3 FeedVM+Filter pairs (#2372), 24 composable files (#2373).

Remaining:

  • ~60 ViewModels (most deeply Android-coupled, need further interface expansion)
  • ~25 FeedViewModels blocked on FilterByListParams in commons
  • Composable moves hitting diminishing returns (blocked on Route/INav unification, R.string, LocalCache)
  • Desktop/iOS platform implementations (deferred until merge review starts)
  • Shadow cast removal (ongoing as interfaces expand)

Session Log

Session Date Duration Agents PRs Key work
1+2 2026-04-12 07:41-13:58 6h17m 40+ #2212-#2279 (37) Foundation, model, theme, resources, composables, navigation
3 2026-04-12 14:01-18:20 4h19m 40 #2280-#2317 (38) IAccount v4-v7, DAL infra, signatures v2-v4, VMs, sealed classes
4 2026-04-12 18:27-21:19 2h52m 29 #2318-#2345 (28) IAccount v8, ICacheProvider v2, FilterByListParams, signatures v5-v7, DAL filter blitz, launchSigner COMPLETE
5 2026-04-12 21:26-00:19 2h53m 33 #2346-#2373 (28) Sig migration COMPLETE (~360 files, 8 PRs), VM batch 9-14, IAccount v9, ICacheProvider v3, DAL batch 11-12, composable batch 16-19, search/community/wallet/relay-mgmt/notification infra

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions