Skip to content

Commit cc75f94

Browse files
committed
IOS-5365 Integrate membership data fetching refactoring for non-blocking startup
Change MembershipStatusStorage to use noCache: false at startup to prevent blocking app launch with network calls. Add membershipTiersUpdate event handler to process async tier updates from middleware. Cache membership and tiers separately for efficient rebuilding.
1 parent d70b49e commit cc75f94

File tree

1 file changed

+48
-11
lines changed

1 file changed

+48
-11
lines changed

Anytype/Sources/ServiceLayer/MembershipStatusStorage/MembershipStatusStorage.swift

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Foundation
22
import ProtobufMessages
33
import Combine
44
import Services
5+
import AnytypeCore
56

67

78
@MainActor
@@ -24,15 +25,18 @@ final class MembershipStatusStorage: MembershipStatusStorageProtocol {
2425
var statusPublisher: AnyPublisher<MembershipStatus, Never> { $_status.eraseToAnyPublisher() }
2526
var currentStatus: MembershipStatus { _status }
2627
@Published private var _status: MembershipStatus = .empty
27-
28+
29+
private var _currentMembership: Anytype_Model_Membership?
30+
private var _cachedTiers: [MembershipTier] = []
31+
2832
private var subscription: AnyCancellable?
2933

3034
nonisolated init() { }
3135

3236
func startSubscription() async {
33-
_status = (try? await membershipService.getMembership(noCache: true)) ?? .empty
37+
_status = (try? await membershipService.getMembership(noCache: false)) ?? .empty
3438
AnytypeAnalytics.instance().setMembershipTier(tier: _status.tier)
35-
39+
3640
setupSubscription()
3741
}
3842

@@ -56,17 +60,50 @@ final class MembershipStatusStorage: MembershipStatusStorageProtocol {
5660
for event in events.middlewareEvents {
5761
switch event.value {
5862
case .membershipUpdate(let update):
59-
Task {
60-
let allTiers = try await membershipService.getTiers()
61-
62-
_status = try builder.buildMembershipStatus(membership: update.data, allTiers: allTiers)
63-
_status.tier.flatMap { AnytypeAnalytics.instance().logChangePlan(tier: $0) }
64-
65-
AnytypeAnalytics.instance().setMembershipTier(tier: _status.tier)
66-
}
63+
handleMembershipUpdate(update)
64+
case .membershipTiersUpdate(let update):
65+
handleMembershipTiersUpdate(update)
6766
default:
6867
break
6968
}
7069
}
7170
}
71+
72+
private func handleMembershipUpdate(_ update: Anytype_Event.Membership.Update) {
73+
Task {
74+
_currentMembership = update.data
75+
76+
if _cachedTiers.isEmpty {
77+
_cachedTiers = (try? await membershipService.getTiers(noCache: false)) ?? []
78+
}
79+
80+
rebuildStatusIfReady()
81+
82+
if let tier = _cachedTiers.first(where: { $0.id == update.data.tier }) {
83+
AnytypeAnalytics.instance().logChangePlan(tier: tier)
84+
}
85+
}
86+
}
87+
88+
private func handleMembershipTiersUpdate(_ update: Anytype_Event.Membership.TiersUpdate) {
89+
Task {
90+
let filteredTiers = update.tiers
91+
.filter { FeatureFlags.membershipTestTiers || !$0.isTest }
92+
93+
_cachedTiers = await filteredTiers.asyncMap { await builder.buildMembershipTier(tier: $0) }.compactMap { $0 }
94+
95+
rebuildStatusIfReady()
96+
}
97+
}
98+
99+
private func rebuildStatusIfReady() {
100+
guard let membership = _currentMembership, !_cachedTiers.isEmpty else { return }
101+
102+
guard let newStatus = try? builder.buildMembershipStatus(membership: membership, allTiers: _cachedTiers) else {
103+
return
104+
}
105+
106+
_status = newStatus
107+
AnytypeAnalytics.instance().setMembershipTier(tier: _status.tier)
108+
}
72109
}

0 commit comments

Comments
 (0)