Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions phoenix-ios/phoenix-ios.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions phoenix-ios/phoenix-ios/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -14452,8 +14452,12 @@
}
}
}
},
"Delete payment history and contacts from my iCloud account." : {

},
"Delete payment history from my iCloud account." : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -14692,8 +14696,12 @@
}
}
}
},
"Deleting **payment history** and **contacts** from iCloud" : {

},
"Deleting **payment history** from iCloud" : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -21793,8 +21801,12 @@
}
}
}
},
"If you switch to a new device (or reinstall the app) then you'll lose this information." : {

},
"If you switch to a new device (or reinstall the app) then you'll lose your payment history." : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -30280,8 +30292,12 @@
}
}
}
},
"Payment history and contacts not stored in iCloud." : {

},
"Payment history not stored in iCloud." : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -31050,6 +31066,7 @@
}
},
"Payments backup" : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -39018,8 +39035,12 @@
}
}
}
},
"The **payment history** and **contacts** for this wallet will be deleted from your iCloud account." : {

},
"The **payment history** for this wallet will be deleted from your iCloud account." : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -48543,8 +48564,15 @@
}
}
}
},
"Your payment history and contacts are only stored on this device." : {

},
"Your payment history and contacts will be stored in iCloud." : {

},
"Your payment history is only stored on this device." : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -48585,6 +48613,7 @@
}
},
"Your payment history will be stored in iCloud." : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down
107 changes: 97 additions & 10 deletions phoenix-ios/phoenix-ios/kotlin/KotlinExtensions+CloudKit.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,54 @@
import Foundation
import PhoenixShared

struct FetchContactsQueueBatchResult {
let rowids: [Int64]
let rowidMap: [Int64: Lightning_kmpUUID]
let rowMap: [Lightning_kmpUUID : ContactInfo]
let metadataMap: [Lightning_kmpUUID : KotlinByteArray]

func uniqueContactIds() -> Set<Lightning_kmpUUID> {
return Set<Lightning_kmpUUID>(rowidMap.values)
}

func rowidsMatching(_ query: Lightning_kmpUUID) -> [Int64] {
var results = [Int64]()
for (rowid, contactId) in rowidMap {
if contactId == query {
results.append(rowid)
}
}
return results
}

func rowidsMatching(_ query: String) -> [Int64] {
var results = [Int64]()
for (rowid, contactId) in rowidMap {
if contactId.id == query {
results.append(rowid)
}
}
return results
}

static func empty() -> FetchContactsQueueBatchResult {

return FetchContactsQueueBatchResult(
rowids: [],
rowidMap: [:],
rowMap: [:],
metadataMap: [:]
)
}
}

struct FetchQueueBatchResult {
struct FetchPaymentsQueueBatchResult {
let rowids: [Int64]
let rowidMap: [Int64: WalletPaymentId]
let rowMap: [WalletPaymentId : WalletPaymentInfo]
let metadataMap: [WalletPaymentId : KotlinByteArray]
let incomingStats: CloudKitDb.MetadataStats
let outgoingStats: CloudKitDb.MetadataStats
let incomingStats: CloudKitPaymentsDb.MetadataStats
let outgoingStats: CloudKitPaymentsDb.MetadataStats

func uniquePaymentIds() -> Set<WalletPaymentId> {
return Set<WalletPaymentId>(rowidMap.values)
Expand All @@ -24,22 +64,69 @@ struct FetchQueueBatchResult {
return results
}

static func empty() -> FetchQueueBatchResult {
func rowidsMatching(_ query: String) -> [Int64] {
var results = [Int64]()
for (rowid, paymentRowId) in rowidMap {
if paymentRowId.id == query {
results.append(rowid)
}
}
return results
}

static func empty() -> FetchPaymentsQueueBatchResult {

return FetchQueueBatchResult(
return FetchPaymentsQueueBatchResult(
rowids: [],
rowidMap: [:],
rowMap: [:],
metadataMap: [:],
incomingStats: CloudKitDb.MetadataStats(),
outgoingStats: CloudKitDb.MetadataStats()
incomingStats: CloudKitPaymentsDb.MetadataStats(),
outgoingStats: CloudKitPaymentsDb.MetadataStats()
)
}
}

extension CloudKitContactsDb.FetchQueueBatchResult {

func convertToSwift() -> FetchContactsQueueBatchResult {

// We are experiencing crashes like this:
//
// for (rowid, paymentRowId) in batch.rowidMap {
// ^^^^^
// Crash: Could not cast value of type '__NSCFNumber' to 'PhoenixSharedLong'.
//
// This appears to be some kind of bug in Kotlin.
// So we're going to make a clean migration.
// And we need to do so without swift-style enumeration in order to avoid crashing.

var _rowids = [Int64]()
var _rowidMap = [Int64: Lightning_kmpUUID]()

for i in 0 ..< self.rowids.count { // cannot enumerate self.rowidMap

let value_kotlin = rowids[i]
let value_swift = value_kotlin.int64Value

_rowids.append(value_swift)
if let contactId = self.rowidMap[value_kotlin] {
_rowidMap[value_swift] = contactId
}
}

return FetchContactsQueueBatchResult(
rowids: _rowids,
rowidMap: _rowidMap,
rowMap: self.rowMap,
metadataMap: self.metadataMap
)
}
}

extension CloudKitDb.FetchQueueBatchResult {
extension CloudKitPaymentsDb.FetchQueueBatchResult {

func convertToSwift() -> FetchQueueBatchResult {
func convertToSwift() -> FetchPaymentsQueueBatchResult {

// We are experiencing crashes like this:
//
Expand All @@ -65,7 +152,7 @@ extension CloudKitDb.FetchQueueBatchResult {
}
}

return FetchQueueBatchResult(
return FetchPaymentsQueueBatchResult(
rowids: _rowids,
rowidMap: _rowidMap,
rowMap: self.rowMap,
Expand Down
14 changes: 14 additions & 0 deletions phoenix-ios/phoenix-ios/kotlin/KotlinExtensions+Other.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ extension WalletBalance {
}
}

extension WalletManager.WalletInfo {

/// All data from a user's wallet are stored in the user's privateCloudDatabase.
/// And within the privateCloudDatabase, we create a dedicated CKRecordZone for each wallet,
/// where recordZone.name == encryptedNodeId.
///
var encryptedNodeId: String {

// For historical reasons, this is the cloudKeyHash, and NOT the nodeIdHash.
// The cloudKeyHash is created via: Hash160(cloudKey)
return self.cloudKeyHash
}
}

extension PhoenixShared.Notification {

var createdAtDate: Date {
Expand Down
6 changes: 6 additions & 0 deletions phoenix-ios/phoenix-ios/kotlin/KotlinIdentifiable.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import Foundation
import PhoenixShared

extension Lightning_kmpUUID: Identifiable {

public var id: String {
return self.description
}
}

extension WalletPaymentId: Identifiable {

Expand Down
30 changes: 26 additions & 4 deletions phoenix-ios/phoenix-ios/kotlin/KotlinPublishers+Phoenix.swift
Original file line number Diff line number Diff line change
Expand Up @@ -396,15 +396,37 @@ extension PaymentsPageFetcher {


// MARK: -
extension CloudKitDb {
extension CloudKitContactsDb {

fileprivate struct _Key {
static var fetchQueueCountPublisher = 0
static var queueCountPublisher = 0
}

func fetchQueueCountPublisher() -> AnyPublisher<Int64, Never> {
func queueCountPublisher() -> AnyPublisher<Int64, Never> {

self.getSetAssociatedObject(storageKey: &_Key.fetchQueueCountPublisher) {
self.getSetAssociatedObject(storageKey: &_Key.queueCountPublisher) {

/// Transforming from Kotlin:
/// `queueCount: StateFlow<Long>`
///
KotlinCurrentValueSubject<KotlinLong>(
self.queueCount
)
.compactMap { $0?.int64Value }
.eraseToAnyPublisher()
}
}
}

extension CloudKitPaymentsDb {

fileprivate struct _Key {
static var queueCountPublisher = 0
}

func queueCountPublisher() -> AnyPublisher<Int64, Never> {

self.getSetAssociatedObject(storageKey: &_Key.queueCountPublisher) {

/// Transforming from Kotlin:
/// `queueCount: StateFlow<Long>`
Expand Down
4 changes: 1 addition & 3 deletions phoenix-ios/phoenix-ios/officers/BusinessManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,6 @@ class BusinessManager {
self.walletInfo = _walletInfo
maybeRegisterFcmToken()

let cloudKey = _walletInfo.cloudKey
let encryptedNodeId = _walletInfo.cloudKeyHash as String

if let walletRestoreType = walletRestoreType {
Expand Down Expand Up @@ -484,8 +483,7 @@ class BusinessManager {
self.syncManager = SyncManager(
chain: business.chain,
recoveryPhrase: recoveryPhrase,
cloudKey: cloudKey,
encryptedNodeId: encryptedNodeId
walletInfo: _walletInfo
)

if LockState.shared.walletExistence == .doesNotExist {
Expand Down
8 changes: 5 additions & 3 deletions phoenix-ios/phoenix-ios/officers/PhotosManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ class PhotosManager {
return photosDir
}()

func genFileName() -> String {
return UUID().uuidString.replacingOccurrences(of: "-", with: "")
}

func urlForPhoto(fileName: String) -> URL {

return photosDirectory.appendingPathComponent(fileName, isDirectory: false)
}

func filePathForPhoto(fileName: String) -> String {

return urlForPhoto(fileName: fileName).path
}

Expand All @@ -97,7 +99,7 @@ class PhotosManager {

func writeToDisk(_ original: PickerResult) async throws -> String {

let fileName = UUID().uuidString.replacingOccurrences(of: "-", with: "")
let fileName = genFileName()
let fileUrl = self.urlForPhoto(fileName: fileName)

let scaled = await original.downscale()
Expand Down
Loading