panpf/zoomimage

Add support for iOS

Closed this issue · 18 comments

Please add support for iOS target in Compose Multiplatform

It’s already in the plan, so stay tuned!

Hi @panpf , do you have any ETA for iOS support?

The alpha version will be released in about two months, because Sketch, the image loader that zoomimage relies on, is about to release a full platform version. After the release, we can start developing the iOS version of zoomimage.

Hey. Any updates/eta on this please?

iOS support is in progress, please follow the progress of the dev branch

Great. Can I try it locally? If yes, which modules should I import. Thanks!

Yes, please follow the steps below:

  1. Switch to the dev branch and update the latest code
  2. Execute ./gradlew publishToMavenLocal
  3. Then you can locally depend on the 1.1.0-SNAPSHOT version of the zoomimage-compose-sketch module
  4. Use the SketchZoomAsyncImage component to load and display the image
  5. Currently you need to depend on the 4.0.0-alpha03 version of sketch, which is being uploaded to the maven repository. If you cannot download the dependency at this time, please wait one to two hours and try again

I'm getting Task 'publishToMavenLocal' not found in root project 'zoomimage' and its subprojects.

Sorry, there was a problem before, it works now, please update the code of the dev branch, I have tested it locally

first impression is that it works great on iOS 🥹
Here's a screen recording - https://drive.google.com/file/d/1bFp8Hr9VswKPVP_GiUiwN-dSYNSaJn2a/view?usp=sharing

This is really good news, and I am glad that you have run it successfully.

At present, the integration of sketch 4 and coil3 has been completed, and you can choose the image loading framework you like.

Next, my work is to refactor the sample app and complete the unit test. When everything is ready, the alpha version can be released. It is expected to take 3 to 4 weeks. Please stay tuned.

That's really great news! @panpf Thank you for the update. I'm looking forward for the alpha version!

Hi, is support for Wasm Web also coming with this update?

The alpha version is expected to be released in about a week, which will support ios, js, and wasmJs

I've tried building it locally following the steps and including it in commonMain.

implementation("io.github.panpf.zoomimage:zoomimage-compose:1.1.0-SNAPSHOT")

(I also tried)

implementation("io.github.panpf.zoomimage:zoomimage-compose-sketch:1.1.0-SNAPSHOT")

While it compiles on Android perfectly, it couldn't compile on wasmJs.

> Task :composeApp:compileDevelopmentExecutableKotlinWasmJs FAILED
e: java.lang.NullPointerException: null cannot be cast to non-null type org.jetbrains.kotlin.descriptors.ClassDescriptor
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.findClass(WasmSymbols.kt:387)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.getClass$backend_wasm(WasmSymbols.kt:396)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.getIrClass(WasmSymbols.kt:416)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.getInternalClass(WasmSymbols.kt:417)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.access$getInternalClass(WasmSymbols.kt:32)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols$WasmReflectionSymbols.<init>(WasmSymbols.kt:64)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.<init>(WasmSymbols.kt:72)
	at org.jetbrains.kotlin.backend.wasm.WasmBackendContext.<init>(WasmBackendContext.kt:117)
	at org.jetbrains.kotlin.backend.wasm.WasmCompilerKt.compileToLoweredIr(wasmCompiler.kt:70)
	at org.jetbrains.kotlin.cli.js.K2JsIrCompiler.doExecute(K2JsIrCompiler.kt:361)
	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:181)
	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:72)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:104)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:48)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1523)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
	at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
	at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.rmi/sun.rmi.transport.Transport.serviceCall(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)


java.lang.NullPointerException: null cannot be cast to non-null type org.jetbrains.kotlin.descriptors.ClassDescriptor
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.findClass(WasmSymbols.kt:387)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.getClass$backend_wasm(WasmSymbols.kt:396)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.getIrClass(WasmSymbols.kt:416)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.getInternalClass(WasmSymbols.kt:417)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.access$getInternalClass(WasmSymbols.kt:32)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols$WasmReflectionSymbols.<init>(WasmSymbols.kt:64)
	at org.jetbrains.kotlin.backend.wasm.WasmSymbols.<init>(WasmSymbols.kt:72)
	at org.jetbrains.kotlin.backend.wasm.WasmBackendContext.<init>(WasmBackendContext.kt:117)
	at org.jetbrains.kotlin.backend.wasm.WasmCompilerKt.compileToLoweredIr(wasmCompiler.kt:70)
	at org.jetbrains.kotlin.cli.js.K2JsIrCompiler.doExecute(K2JsIrCompiler.kt:361)
	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:181)
	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:72)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:104)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:48)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1523)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
	at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
	at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.rmi/sun.rmi.transport.Transport.serviceCall(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)



Execution failed for task ':composeApp:compileDevelopmentExecutableKotlinWasmJs'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
   > Internal compiler error. See log for more details

I can't tell you directly what the problem is and how to solve it, because it's beyond my ability, and it should be the ability of the kmp team.

But I can tell you that my sample app can run normally, so there may be something wrong with your configuration or environment.

I suggest you try the following solutions to solve the problem:

  1. Download a new project template containing wasmJs from https://kmp.jetbrains.com and run it directly.

  2. After running successfully, import the dependency of zoomimage and write an example. This step should be fine.

  3. Finally, compare the configuration of your project to find out the problem

Thank you for the advice, I've managed to find the root of the problem. It was because I was using Kotlin 1.9.24 instead of 2.0.0.
The library works well on wasmJs. However, the zoom controls with the mouse on the web browser are a bit confusing. Dragging in random directions sometimes registers as zoom while other times as panning.
I also suggest adding the option to use the scroll wheel to zoom in/out as you do with things like Google Maps.

Version 1.1.0-alph01, which supports iOS, js, and wasmJS, has been released. You are welcome to try it and give us feedback.

https://github.com/panpf/zoomimage/releases/tag/1.1.0-alpha01

Next we will focus on optimizing experience issues and unit testing