Browse Source

Fix a resource reading on iOS 12 (#5123)

Use deprecated `seekToFileOffset` on iOS 12 to fix a crash on old Apple
devices

Fixes https://youtrack.jetbrains.com/issue/CMP-5967

## Release Notes
### Fixes - Resources
- _(prerelease fix)_ Fix a resource reading on iOS 12
pull/5125/head
Konstantin 3 months ago committed by GitHub
parent
commit
7d0bf7b831
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 31
      components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt

31
components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt

@ -1,10 +1,29 @@
package org.jetbrains.compose.resources
import kotlinx.cinterop.BetaInteropApi
import kotlinx.cinterop.ObjCObjectVar
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.alloc
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.ptr
import kotlinx.cinterop.usePinned
import platform.Foundation.*
import kotlinx.cinterop.value
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.OSVersion
import org.jetbrains.skiko.available
import platform.Foundation.NSBundle
import platform.Foundation.NSData
import platform.Foundation.NSError
import platform.Foundation.NSFileHandle
import platform.Foundation.NSFileManager
import platform.Foundation.NSURL
import platform.Foundation.closeFile
import platform.Foundation.fileHandleForReadingAtPath
import platform.Foundation.readDataOfLength
import platform.Foundation.seekToFileOffset
import platform.posix.memcpy
@OptIn(BetaInteropApi::class)
internal actual fun getPlatformResourceReader(): ResourceReader = object : ResourceReader {
override suspend fun read(path: String): ByteArray {
val data = readData(getPathInBundle(path))
@ -30,7 +49,15 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou
private fun readData(path: String, offset: Long, size: Long): NSData {
val fileHandle = NSFileHandle.fileHandleForReadingAtPath(path) ?: throw MissingResourceException(path)
fileHandle.seekToOffset(offset.toULong(), null)
if (available(OS.Ios to OSVersion(major = 13))) {
memScoped {
val error = alloc<ObjCObjectVar<NSError?>>()
fileHandle.seekToOffset(offset.toULong(), error.ptr)
error.value?.let { err -> error(err.localizedDescription) }
}
} else {
fileHandle.seekToFileOffset(offset.toULong())
}
val result = fileHandle.readDataOfLength(size.toULong())
fileHandle.closeFile()
return result

Loading…
Cancel
Save