wip
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package com.mycrib.platform
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.interop.LocalUIViewController
|
||||
import kotlinx.cinterop.*
|
||||
import platform.Foundation.*
|
||||
import platform.PhotosUI.*
|
||||
import platform.UIKit.*
|
||||
import platform.darwin.NSObject
|
||||
import platform.posix.memcpy
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
@Composable
|
||||
actual fun rememberImagePicker(
|
||||
onImagesPicked: (List<ImageData>) -> Unit
|
||||
): () -> Unit {
|
||||
val viewController = LocalUIViewController.current
|
||||
|
||||
val pickerDelegate = remember {
|
||||
object : NSObject(), PHPickerViewControllerDelegateProtocol {
|
||||
override fun picker(
|
||||
picker: PHPickerViewController,
|
||||
didFinishPicking: List<*>
|
||||
) {
|
||||
picker.dismissViewControllerAnimated(true, null)
|
||||
|
||||
val results = didFinishPicking as List<PHPickerResult>
|
||||
if (results.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val images = mutableListOf<ImageData>()
|
||||
var processedCount = 0
|
||||
|
||||
results.forEach { result ->
|
||||
val itemProvider = result.itemProvider
|
||||
|
||||
// Check if the item has an image using UTType
|
||||
if (itemProvider.hasItemConformingToTypeIdentifier("public.image")) {
|
||||
itemProvider.loadFileRepresentationForTypeIdentifier(
|
||||
typeIdentifier = "public.image",
|
||||
completionHandler = { url, error ->
|
||||
if (error == null && url != null) {
|
||||
// Read the image data from the file URL
|
||||
val imageData = NSData.dataWithContentsOfURL(url)
|
||||
if (imageData != null) {
|
||||
// Convert to UIImage and then to JPEG for consistent format
|
||||
val image = UIImage.imageWithData(imageData)
|
||||
if (image != null) {
|
||||
val jpegData = UIImageJPEGRepresentation(image, 0.8)
|
||||
if (jpegData != null) {
|
||||
val bytes = jpegData.toByteArray()
|
||||
val fileName = "image_${NSDate().timeIntervalSince1970.toLong()}_${processedCount}.jpg"
|
||||
synchronized(images) {
|
||||
images.add(ImageData(bytes, fileName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processedCount++
|
||||
|
||||
// When all images are processed, call the callback
|
||||
if (processedCount == results.size) {
|
||||
if (images.isNotEmpty()) {
|
||||
onImagesPicked(images.toList())
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
processedCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
val config = PHPickerConfiguration().apply {
|
||||
setSelectionLimit(5)
|
||||
setFilter(PHPickerFilter.imagesFilter())
|
||||
}
|
||||
|
||||
val picker = PHPickerViewController(config).apply {
|
||||
setDelegate(pickerDelegate)
|
||||
}
|
||||
|
||||
viewController.presentViewController(picker, animated = true, completion = null)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
private fun NSData.toByteArray(): ByteArray {
|
||||
return ByteArray(length.toInt()).apply {
|
||||
usePinned {
|
||||
memcpy(it.addressOf(0), bytes, length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T : Any> synchronized(lock: Any, block: () -> T): T {
|
||||
return block()
|
||||
}
|
||||
Reference in New Issue
Block a user