SDWebImage / SDWebImageSwiftUI

SwiftUI Image loading and Animation framework powered by SDWebImage
https://sdwebimage.github.io/SDWebImageSwiftUI
MIT License
2.21k stars 230 forks source link

Is it possible to lower the Minimum Deployment Target? #66

Closed djr closed 4 years ago

djr commented 4 years ago

I'm working on an app where we are supporting older iOS versions, but using SwiftUI for iOS 13 users. How difficult would it be to lower the deployment target?

This is the error that I'm getting when attempting to install the CocoaPod:

[!] CocoaPods could not find compatible versions for pod "SDWebImageSwiftUI": In Podfile: SDWebImageSwiftUI

Specs satisfying the SDWebImageSwiftUI dependency were found, but they required a higher minimum deployment target.

Thanks for the help!

dreampiggy commented 4 years ago

You can always specify your deployment target during CocoaPods’s validation, this does not effect your project’s configuration (just a hint to allows pod install)

platform :ios, '13.0'

But actually, since all code have that import SwiftUI, doesn’t this will cause a link error on iOS 12 device (until Apple using weak framework for SwiftUI, this is a implementation detail) ? This need a experiment

djr commented 4 years ago

Thanks for the quick reply!

I tried changing it to platform :ios, '12.0' but it didn't allow me to install it.

In my project the compiler doesn't complain about the import SwiftUI, I just had to put @available(iOS 13, *) everywhere.

I was able to install it using Swift Packages, but then I got a compiler error on the import SDWebImageSwiftUI statement.

djr commented 4 years ago

So I created a fork and I was able to get the app compiling using Swift Packages. All I had to do was change the iOS deployment target and add a bunch of @available(iOS 13, *) statements.

Here's my fork in case you are interested in looking at the changes.
https://github.com/djr/SDWebImageSwiftUI/commits/master

I only focused on the Swift Package for now. More updates will be needed to support Carthage and CocoaPods.

The SwiftUI WebImage is exactly what I was looking for. Thanks @dreampiggy for working on this project!

dreampiggy commented 4 years ago

@djr My worry is that : Does that chaning min deployment target version works ?

In fact, if a framework is not weak linked, even you can compile that framework into the binary, it will trigger the dyld (dynamic linker runtime) error after App launch. Because the symbol does not exist on iOS 13 pre devices. You can not bundle a SwiftUI.framework into your ipa app as well.

dreampiggy commented 4 years ago

And. Even this Technocally works, this may not a be good idea in practice. Think of that:

If I want to use SwiftUI on iOS 13 deployment client, using UIKit on iOS 12 deployment target. Should I write the same UI code twice ?

This is what I think it's not a good idea. Which increase your code complicity, and waste extra time to keep the sync function of your UI between UIKit/SwiftUI. The same as bugfix and features. This may become a huge pain on your team's long maintain.

And even worse on the App binary size. Because iOS does not support you to deployment different code between the different versions. If I'm a iOS 12 user, why The App download size become larger because of iOS 13 SwiftUI code ? That's unrelated to me.

djr commented 4 years ago

This is an existing app and we are continuing to support the iOS 12 users just in case there are any critical bugs. All future development will be on the iOS 13 UI code. We will definitely push all of our users to upgrade and drop iOS 12 support as soon as possible. We aren't concerned with the app binary size since we have plenty of breathing room. The dyld error can be resolved by adding -weak_framework SwiftUI to Other Linker Flags.

mknippen commented 4 years ago

+1 to this issue and project!

I've also faced a similar issue. Here's our background: We have an app that we want to move completely to SwiftUI. However, we cannot yet drop support for iOS 12. So, we've made the decision to keep the app exactly how it is for older devices, and write our new features with SwiftUI.

We've included a prompt for older devices to upgrade, and we will drop support for iOS 12 next year. This allows us to build all of our SwiftUI components this year, and gain all of the dev increases for using Apple's latest tools.

If this is easily possible to update, I'd love to use it!

dreampiggy commented 4 years ago

@djr @mknippen

I think I can do is to Add all the #available annotation in all Public APIs, but still keep the min deployment target version in iOS 13.0. Because I'm a framework author, should maintain this framework to go on. Chaning the min deployment target version will hide some warning, and actually, this framework does not works on iOS 12.0)

The min deployment target version, actually does nothing, even it stay at 13.0, it can still be compiled, linked (with a link warning maybe, SDWebImageSwiftUI is built for high version iOS 13.0, but the linked binary is built for version iOS 12.0, blabla`).

For CocoaPods user, you can always workaround to specify a desired deployment target version during validation (This validation is useless), which does not effect your App's itself deployment target version. For Cathage/SwiftPM user, you can ignore the warning and start using it.

When using the framework, you should specify that this framework is optional (or, weak_framework in Other Linker Flags).

image

dreampiggy commented 4 years ago

After my local test, it works now, no need to modify the min deployment target version. Just need some hack:

See my code changes here: https://github.com/SDWebImage/SDWebImageSwiftUI/compare/project_add_available_for_lower_firmware_version

image

  1. Each individual framework, should enable BUILD_LIBRARY_FOR_DISTRIBUTION = YES
  2. Each individual framework, should add weak linking for both SwiftUI and Combine by OTHER_LDFLAGS = -weak_framework Combine -weak_framework SwiftUI
djr commented 4 years ago

Wow this is great @dreampiggy! Thanks for your support.

mknippen commented 4 years ago

Thank you so much, this is awesome!

djr commented 4 years ago

@dreampiggy how did you add this to your project?

Is it possible to make it work with CocoaPods?

[!] CocoaPods could not find compatible versions for pod "SDWebImageSwiftUI": In Podfile: SDWebImageSwiftUI (from https://github.com/SDWebImage/SDWebImageSwiftUI.git, branch project_add_available_for_lower_firmware_version)

Specs satisfying the SDWebImageSwiftUI (fromhttps://github.com/SDWebImage/SDWebImageSwiftUI.git, branchproject_add_available_for_lower_firmware_version) dependency were found, but they required a higher minimum deployment target.

dreampiggy commented 4 years ago

That branch contains some extra changes, I'll ammend them on and merge into master, later (I'm busy recently)

@djr For CocoaPods, it have a extra validation (Which I don't think it useful). You can just ignore it. This does not effect your App target's deployment target, only effect the Pods.xcodeproj target, and does not effect each individual Pods target as well (each Pods's deployment target version is configuated by its Podspec information, not this one), actually useless.

# Podfile
platform :ios, '13.0'
dreampiggy commented 4 years ago

@djr @mknippen Already supported now. I've add annotation to all the public API, also change the build settings to only weak linking of SwiftUI && Combine.

I've released v0.10.0 with these changes, also update the readme. See more information there.


Note this works for only CocoaPods and Carthage. SwiftPM, however, is sucked that you can not using weak linking (it have a unsafeFlags() to pass -weak_framework SwiftUI -weak_framework Combine, however, Xcode does not support this 🙃🙃🙃)

The package product 'SDWebImageSwiftUI' cannot be used as a dependency of this target because it uses unsafe build flags.

You can have a try with my local demo, which showing the usage with SDWebImageSwiftUI and backward deploy to iOS 12.

TestUIKitSwiftUIiOS12.zip

djr commented 4 years ago

Thank you @dreampiggy! You rock!