SkiaKit icon indicating copy to clipboard operation
SkiaKit copied to clipboard

Convert to only SwiftPM, use XCFramework on Apple systems

Open mbullington opened this issue 3 years ago • 16 comments

Hey Miguel!

Thanks for being super awesome about patches and working with me on this.

Summary of the changes:

  • Removed old XCode project and switched entirely to SwiftPM.
  • Changed how payloads are downloaded:
  • If on Linux, download SkiaSharp.NativeAssets.Linux and extract the .so that supports these distros: https://github.com/mono/SkiaSharp/issues/453
  • If on macOS, download SkiaSharp and extract a bunch of .frameworks, lipo them separate architectures (.xcframework limitation), then make a new SkiaSharp.xcframework that can be used by SwiftPM/XCode.
  • Moved around (not sure if will stick) headers and "shared" code so it was included when you list SkiaKit as a dependency in Swift Package Manager. The XCode sample app uses the XCode 11+ SwiftPM integration and works great.
  • The Apple components that interact with UIView and CALayer I switched to use #if canImport(UIKit) and #if canImport(QuartzCore). They'll just not be included on Linux/other but I think this'll work out of the box with macOS Catalyst.

How to use:

I added a GH action that downloads both payloads and then 'publishes' them to a branch named generated. SwiftPM/XCode projects can use this branch directly and not need to build anything. On Linux I think you'd still need to ship the .so alongside the project.

Unfortunately, SwiftPM integration in XCode requires a git repository and cannot do relative/absolute file paths. To fit this model I had to split out the samples into a separate repo: https://github.com/bloomos/SkiaKitSamplesiOS

Below is the process required to add SkiaKit to a SwiftUI project (in the video, my sunset app Twilight!) and a video of the example app running.

https://user-images.githubusercontent.com/6068785/132260302-960d9d73-f6f3-418b-93fd-36bfa2adead3.mov

https://user-images.githubusercontent.com/6068785/132260305-e13e287a-d367-4369-b9aa-83a510ce5004.mov

Thanks again!

mbullington avatar Mar 06 '21 20:03 mbullington

Hello!

Thank you for this contribution! Apologies, I am usually spammed with notifications, and I guess this did not show up on my dashboard.

I will review and see if I can merge it, thank you so much for doing that work!

migueldeicaza avatar Apr 30 '21 22:04 migueldeicaza

I tried using the pull request, but I am not quite sure how to produce a binary artifact that can be reused.

The download script certainly produces a newer version of the xcframework, but I do not know how I am supposed to use SkiaKit itself after this change.

Lastly, I do not mind dropping Xcode support for the build that I had, and move entirely to SwiftPM, as it has never been a pleasant experience. I would want to ship some working samples for the assorted platforms, but would love some guidance as to how I am supposed to reference the Swift package

migueldeicaza avatar May 02 '21 04:05 migueldeicaza

Hey @migueldeicaza ! Thanks for your patience here, I've been moving and doing a lot of personal tasks to get settled.

I hope I answered most of your questions in the Description, I'm going to update the READMEs soon but feel this is ready for review.

I also made some more bindings for my Wayland project, but one change at a time. :)

Best,

mbullington avatar Sep 06 '21 21:09 mbullington

Last thing I think this PR needs fixed is this, I'm sure there's a really easy solution but I'm not super versed in Linux shared library linking.

https://github.com/bloomos/SkiaKit/runs/3528061024?check_suite_focus=true

mbullington avatar Sep 06 '21 21:09 mbullington

Also there was an issue that was crashing my real iPhone in SkiaView.swift and SkiaCanvasLayer.swift. I was able to fix by persisting the bitmap data until next render or deinit, the same functionality as SkiaSharp.

https://github.com/mono/SkiaSharp/blob/main/source/SkiaSharp.Views/SkiaSharp.Views.Apple/SKCGSurfaceFactory.cs

mbullington avatar Sep 07 '21 02:09 mbullington

Hello Michael,

This looks like an amazing patch! I will review it and hopefully merge it soon, and will try to address the couple of issues that you brought up on this thread.

I have myself just moved, exactly 14 days ago, and we have been slowly unpacking, and have been generally exhausted after a long day of unpacking, and today was my first evening checking Github. It might take me a couple more days, but fear not, I am on the case.

Thanks once again!

migueldeicaza avatar Sep 20 '21 02:09 migueldeicaza

Hello Michael,

This looks like an amazing patch! I will review it and hopefully merge it soon, and will try to address the couple of issues that you brought up on this thread.

I have myself just moved, exactly 14 days ago, and we have been slowly unpacking, and have been generally exhausted after a long day of unpacking, and today was my first evening checking Github. It might take me a couple more days, but fear not, I am on the case.

Congrats on the move! Take as much time as you need :)

Thanks once again!

mbullington avatar Sep 20 '21 13:09 mbullington

Hello,

I have a question about this:

Unfortunately, SwiftPM integration in XCode requires a git repository and cannot do relative/absolute file paths. To fit this model I had to split out the samples into a separate repo: https://github.com/bloomos/SkiaKitSamplesiOS

Does the challenge happen when you try to reference this repository from another project, and any samples conflict, or it means that Xcode is unable to open a Package.swift that contains iOS samples as well?

migueldeicaza avatar Sep 28 '21 14:09 migueldeicaza

In particular, I wonder if this might work:

https://developer.apple.com/documentation/swift_packages/developing_a_swift_package_in_tandem_with_an_app

migueldeicaza avatar Sep 28 '21 14:09 migueldeicaza

I love the patch, and I think I can make the samples work with the above approach.

That said, one thing that is worrying me a bit, is the use of the "generated" branch to deploy the artifacts.

The generated branch will bloat the GitHub repo with binaries, but most importantly, they will override other versions over time, making historically different versions of SkiaKit not work, or break behind the scenes of people that end up using that branch over time.

I wonder if there are other options that we could use to get the binary artifacts that does not rely on that. branch.

migueldeicaza avatar Sep 28 '21 15:09 migueldeicaza

Additional thoughts: I wonder if rather than publishing to a branch generated if this can publish an official release, which would have the advantage of not bloating the repository, and could be versioned. The secondary question is whether this can publish the full "tree" as expected by SwiftPM, or if it can only publish the binary artifacts.

migueldeicaza avatar Sep 28 '21 17:09 migueldeicaza

Additional Research:

  • Perhaps we could publish the XCFramework artifact as a release through some other way, which would cover the Apple platforms.
  • For other platforms, the Package.swift could run a function that would download the asset before the targets are defined.

migueldeicaza avatar Sep 28 '21 18:09 migueldeicaza

Ok did a quick script that will download+publish binary artifacts here:

https://github.com/migueldeicaza/SkiaKitPayloads/releases

(The source for this is there as well). Will try tomorrow to switch the binary dependecy to this on MacOS, and do the unsavory hack on Linux.

migueldeicaza avatar Sep 29 '21 02:09 migueldeicaza

Were there any updates on this one? We're just about to start a project that would love to make use of this.

Allan121 avatar Nov 10 '21 05:11 Allan121

Apologies, I forgot where I was at.

I would need to resume the work :-)

migueldeicaza avatar Feb 04 '22 17:02 migueldeicaza

Additional details, we could use this for SwiftPM 5.6:

https://github.com/apple/swift-evolution/blob/main/proposals/0305-swiftpm-binary-target-improvements.md

migueldeicaza avatar Mar 02 '22 15:03 migueldeicaza