refactor(platform): remove Apple targets from KMP

This commit is contained in:
2026-07-21 17:09:59 +02:00
parent d8eaf78997
commit 9e8564e013
75 changed files with 118 additions and 2930 deletions

View File

@@ -134,13 +134,6 @@ interface CoreGateway {
senderName: String,
accessPolicy: ShareAccessPolicy,
): Result<Share>
suspend fun shareSecurityScopedFileUrl(
fileUrl: String,
displayName: String,
transferName: String,
senderName: String,
accessPolicy: ShareAccessPolicy,
): Result<Share>
/** Multi-source share used by multi-file pickers. */
suspend fun shareSources(
sources: List<uniffi.vnidrop.ShareSource>,
@@ -151,7 +144,6 @@ interface CoreGateway {
suspend fun inspectTicket(ticket: String): Result<TicketInspectionModel>
suspend fun receive(ticket: String, outputDir: String, receiverName: String): Result<Unit>
suspend fun receiveWithOutputSink(ticket: String, outputSink: ReceiveOutputSink, receiverName: String): Result<Unit>
suspend fun receiveIntoSecurityScopedDirectory(ticket: String, outputDirectoryUrl: String, receiverName: String): Result<Unit>
suspend fun cancel(transferId: ULong): Result<Unit>
suspend fun delete(transferId: ULong): Result<Unit>
suspend fun clearReceiveHistory(): Result<ULong>

View File

@@ -113,27 +113,6 @@ class CoreRepository(
accessPolicy = accessPolicy,
)
override suspend fun shareSecurityScopedFileUrl(
fileUrl: String,
displayName: String,
transferName: String,
senderName: String,
accessPolicy: ShareAccessPolicy,
): Result<Share> =
shareSources(
sources = listOf(
ShareSource(
kind = SourceKind.IOS_SECURITY_SCOPED_URL,
value = fileUrl,
displayName = displayName.ifBlank { fileUrl.substringAfterLast('/').ifBlank { "transfer" } },
isDirectory = false,
),
),
transferName = transferName,
senderName = senderName,
accessPolicy = accessPolicy,
)
override suspend fun inspectTicket(ticket: String): Result<TicketInspectionModel> = runCore {
requireCore().inspectTicket(ticket).toModel().also { inspection ->
_state.update { it.copy(lastInspection = inspection) }
@@ -154,17 +133,6 @@ class CoreRepository(
refreshSnapshot()
}
override suspend fun receiveIntoSecurityScopedDirectory(
ticket: String,
outputDirectoryUrl: String,
receiverName: String,
): Result<Unit> = runCore {
withPlatformPathAccess(SourceKind.IOS_SECURITY_SCOPED_URL, outputDirectoryUrl) {
requireCore().receive(ticket, outputDirectoryUrl, receiverName.ifBlank { null })
}
refreshSnapshot()
}
override suspend fun cancel(transferId: ULong): Result<Unit> = runCore {
requireCore().cancelTransfer(transferId)
refreshSnapshot()

View File

@@ -10,9 +10,9 @@ data class PickedShareFile(
/** App-owned picker copy that may be deleted after import or when selection is abandoned. */
val isTemporaryCopy: Boolean = false,
/**
* When true, [value] is a directory (filesystem path, iOS security-scoped
* folder URL, or Android document tree URI). Platform share code expands or
* walks it; Rust cannot treat an Android FD as a directory.
* When true, [value] is a directory (filesystem path or Android document tree
* URI). Platform share code expands or walks it; Rust cannot treat an Android
* FD as a directory.
*/
val isDirectory: Boolean = false,
)

View File

@@ -8,7 +8,6 @@ enum class ReceiveFolderKind {
/** Shared system Downloads via MediaStore (Android 10+). */
AndroidPublicDownloads,
AndroidTreeUri,
IosSecurityScopedUrl,
}
/** Stable token stored in preferences for [ReceiveFolderKind.AndroidPublicDownloads]. */

View File

@@ -2,10 +2,8 @@ package com.vnidrop.app.core
import uniffi.vnidrop.SourceKind
// Platform file handles have different lifetime rules. Desktop paths need no
// extra work, Rust duplicates Android fd sources immediately, and iOS
// security-scoped URLs must remain leased while Rust performs the blocking
// import/export call.
// Desktop paths need no extra work, while Rust duplicates borrowed Android file
// descriptors immediately before the platform closes them.
internal expect suspend fun <T> withPlatformPathAccess(
kind: SourceKind,
value: String,

View File

@@ -161,14 +161,10 @@ class ReceiveViewModel(
it.copy(isReceiving = true, lastReceiveError = null, activeReceiveTransferId = null)
}
val outputSink = fileSystemService.createReceiveOutputSink(folder)
val result = when {
outputSink != null -> repository.receiveWithOutputSink(current.ticket, outputSink, current.receiverName)
folder.kind == ReceiveFolderKind.IosSecurityScopedUrl -> repository.receiveIntoSecurityScopedDirectory(
current.ticket,
folder.value,
current.receiverName,
)
else -> repository.receive(current.ticket, folder.value, current.receiverName)
val result = if (outputSink != null) {
repository.receiveWithOutputSink(current.ticket, outputSink, current.receiverName)
} else {
repository.receive(current.ticket, folder.value, current.receiverName)
}
result.fold(
onSuccess = {