Implement proper iOS structure

This commit is contained in:
2025-12-06 12:17:40 +03:00
Unverified
parent 7696d26fd3
commit b95820de6c
36 changed files with 811 additions and 87 deletions
@@ -1,23 +1,33 @@
package com.pr0gramm3r101.utils.crypto
import kotlinx.cinterop.BetaInteropApi
import kotlinx.cinterop.ByteVar
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.get
import kotlinx.cinterop.reinterpret
import kotlinx.cinterop.usePinned
import platform.Foundation.NSData
import platform.Foundation.base64EncodedStringWithOptions
import platform.Foundation.create
actual object Base64 {
@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class)
actual fun encode(bytes: ByteArray): String {
return bytes.usePinned { pinned ->
val nsData = NSData.create(bytes = pinned.addressOf(0), length = bytes.size.toULong())
nsData.base64EncodedStringWithOptions(0u)
}
}
@OptIn(BetaInteropApi::class, ExperimentalForeignApi::class)
actual fun decode(base64: String): ByteArray {
val nsData = NSData.create(base64EncodedString = base64, options = 0u) ?: return ByteArray(0)
val length = nsData.length.toInt()
val bytes = nsData.bytes ?: return ByteArray(0)
val bytesPtr = nsData.bytes ?: return ByteArray(0)
val bytePtr = bytesPtr.reinterpret<ByteVar>()
return ByteArray(length) { index ->
bytes.reinterpret<ByteVar>()[index]
bytePtr[index]
}
}
}
}
@@ -1,11 +1,15 @@
package com.pr0gramm3r101.utils.crypto
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.usePinned
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import platform.CommonCrypto.CCHmac
import platform.CommonCrypto.kCCHmacAlgSHA256
import platform.CoreCrypto.CCHmac
import platform.CoreCrypto.kCCHmacAlgSHA256
actual object Hmac {
@OptIn(ExperimentalForeignApi::class)
actual suspend fun hmacSha256(key: ByteArray, data: ByteArray): ByteArray = withContext(Dispatchers.Default) {
val result = ByteArray(32)
@@ -3,11 +3,12 @@ package com.pr0gramm3r101.utils.settings
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import platform.Foundation.NSUserDefaults
import platform.Foundation.NSBundle
class IosAsyncSettings : AsyncSettings {
private val defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults
override suspend fun putString(key: String, value: String) = withContext(Dispatchers.Default) {
override suspend fun putString(key: String, value: String): Unit = withContext(Dispatchers.Default) {
defaults.setObject(value, key)
defaults.synchronize()
}
@@ -16,7 +17,7 @@ class IosAsyncSettings : AsyncSettings {
defaults.stringForKey(key) ?: default
}
override suspend fun putInt(key: String, value: Int) = withContext(Dispatchers.Default) {
override suspend fun putInt(key: String, value: Int): Unit = withContext(Dispatchers.Default) {
defaults.setInteger(value.toLong(), key)
defaults.synchronize()
}
@@ -26,7 +27,7 @@ class IosAsyncSettings : AsyncSettings {
if (value != null) value.toInt() else default
}
override suspend fun putLong(key: String, value: Long) = withContext(Dispatchers.Default) {
override suspend fun putLong(key: String, value: Long): Unit = withContext(Dispatchers.Default) {
defaults.setObject(value, key)
defaults.synchronize()
}
@@ -35,7 +36,7 @@ class IosAsyncSettings : AsyncSettings {
(defaults.objectForKey(key) as? platform.Foundation.NSNumber)?.longValue ?: default
}
override suspend fun putFloat(key: String, value: Float) = withContext(Dispatchers.Default) {
override suspend fun putFloat(key: String, value: Float): Unit = withContext(Dispatchers.Default) {
defaults.setFloat(value, key)
defaults.synchronize()
}
@@ -45,7 +46,7 @@ class IosAsyncSettings : AsyncSettings {
if (value != null) value.toFloat() else default
}
override suspend fun putBoolean(key: String, value: Boolean) = withContext(Dispatchers.Default) {
override suspend fun putBoolean(key: String, value: Boolean): Unit = withContext(Dispatchers.Default) {
defaults.setBool(value, key)
defaults.synchronize()
}
@@ -58,7 +59,7 @@ class IosAsyncSettings : AsyncSettings {
}
}
override suspend fun putStringSet(key: String, value: Set<String>) = withContext(Dispatchers.Default) {
override suspend fun putStringSet(key: String, value: Set<String>): Unit = withContext(Dispatchers.Default) {
defaults.setObject(value.toList(), key)
defaults.synchronize()
}
@@ -68,7 +69,7 @@ class IosAsyncSettings : AsyncSettings {
list.filterIsInstance<String>().toSet()
}
override suspend fun putStringList(key: String, value: List<String>) = withContext(Dispatchers.Default) {
override suspend fun putStringList(key: String, value: List<String>): Unit = withContext(Dispatchers.Default) {
defaults.setObject(value, key)
defaults.synchronize()
}
@@ -78,7 +79,7 @@ class IosAsyncSettings : AsyncSettings {
list.filterIsInstance<String>()
}
override suspend fun remove(key: String) = withContext(Dispatchers.Default) {
override suspend fun remove(key: String): Unit = withContext(Dispatchers.Default) {
defaults.removeObjectForKey(key)
defaults.synchronize()
}
@@ -87,8 +88,9 @@ class IosAsyncSettings : AsyncSettings {
defaults.objectForKey(key) != null
}
override suspend fun clear() = withContext(Dispatchers.Default) {
val domain = defaults.persistentDomainForName(defaults.bundleIdentifier() ?: "")
override suspend fun clear(): Unit = withContext(Dispatchers.Default) {
val bundleId = NSBundle.mainBundle.bundleIdentifier ?: ""
val domain = defaults.persistentDomainForName(bundleId)
domain?.keys?.forEach { key ->
defaults.removeObjectForKey(key as String)
}
@@ -96,4 +98,4 @@ class IosAsyncSettings : AsyncSettings {
}
}
actual val asyncSettings: AsyncSettings = IosAsyncSettings()
actual val asyncSettings: AsyncSettings = IosAsyncSettings()