I have a Swift class which is linked against several targets with different deployment targets, the main project has iOS 7 minimum requirement and there is an extension with iOS 8 target.
Now when I compile project, the compiler throws warning on this line of code:
if #available(iOS 8.0, *) { ... }
"Unnecessary check for 'iOSApplicationExtension'; minimum deployment target ensures guard will always be true"
I have checked build settings options and found no switch to kill swift warnings.
I tried to define iOSApplicationExtension version target separately by this line but without success:
if #available(iOS 8.0, iOSApplicationExtension 8.0, *) { ... }
Is there any way to suppress this annoying message?
Found an ugly workaround to silence warning, but I hope there is a better way:
In iOS 8+ targets build settings, I defined a precompile flag in Build Settings -> Swift Compiler - Custom Flags -> Other Swift Flags:
-D iOS8target
Then I changed code to this way:
#if iOS8target
// iOS 8+ compatible code
#else
if #available(iOS 8.0, *) {
// repeat iOS 8+ compatible code again!
} else {
// iOS 7 code
}
#endif
It's not refactored and ugly, but it works!
UPDATE:
There is a swift compiler switch -suppress-warnings to omit all warnings. But it also suppress useful warnings.
Also if there is only one specific file which emits warnings, you can use -w flag in Building Phases pane. It will also suppress useful warnings but limited to one file.
The next release of Cocoapod (after 0.39.0) should have this issue addressed. Check this for more details.
Please check your deployment target into your General and set from 9.0
to 7.0 or less. this warning will remove automatically.
Related
When archiving/building the app which uses SwiftUI for platforms <= iOS 10, the compiler throws errors "Use of undeclared type".
This happens even if the enclosing type is marked as #available(iOS 13.0, *) and also using #if canImport(SwiftUI).
SwiftUI framework is also weakly linked.
Everything works fine if you are running(debug) on an iOS 11+ device, or archiving for a target with minimum supported version <= iOS 11.
This failure occurs because builds with a deployment target earlier than iOS 11 will also build for the armv7 architecture, and there is no armv7 swiftmodule for SwiftUI in the iOS SDK because the OS version in which it was first introduced (iOS 13) does not support armv7 anymore.
I have managed to solve the archiving issue by wrapping the SwiftUI Code/Files in the preprocessor of #if arch(arm64).
Example -
#if arch(arm64)
#available(iOS 13.0, *)
struct MyCustomView: View {
var myStrings: [String]
var body: some View {
List {
ForEach(myStrings) { str in
Text(str)
}
}
}
}
#endif
This does disable previews in cases if your deployment target is <= iOS 10.
But if used only when archiving, this does work.
If anyone knows of a better solution. Please share.
Adding this answer so that someone in my situation can atleast make it work with SwiftUI.
Cheers!
RealityKit is only available on iOS 13.0 and up and when I try to integrate it to my project and run it on iOS 12.0 or below, the app crashes with abort_with_payload error.
I still want my app to run on iOS 9.0 - iOS 12.0 without the AR feature. Is there a way I can do that?
This happens because the framework RealityKit always imports even though the device does not have that framework. The solution is to make it optional based on the device you are using.
Go to you project's Build Settings.
Go to Linking -> Other linker Flags
Double click Other linker Flags values to add a new one.
Press add button then type -weak_framework RealityKit
That should do it. Enter then run your app.
Hope this helps. Happy Coding. :D
Have a look at the canImport(module) directive
#if canImport(RealityKit)
import RealityKit
#endif
#available(iOS 13.0, *)
class MyClassWhichUsesRealityKit {
func do() {
let v = ARView(frame: .zero)
}
}
Source: https://github.com/apple/swift-evolution/blob/master/proposals/0075-import-test.md
I'm trying to add support for newer iOS devices while maintaining compatibility with older ones. Using Xcode 11.1, I've set the target iOS platform to 9.3, in General -> Deployment Info -> Target.
In Build Settings, the Base SDK just says iOS, so I'm assuming it's always the latest that Xcode supports.
I'm trying to make the Home Indicator disappear in iPhoneX and 11, but for that you have to override this method,
override func prefersHomeIndicatorAutoHidden() -> Bool
{
return true
}
However, I get this build error:
Method does not override any method from its superclass
I tried using the #available syntax like this,
#available(iOS 11.0, *)
override func prefersHomeIndicatorAutoHidden() -> Bool
{
return true
}
But I get the same build error. If I check the Quick Help on that method, it doesn't point to Apple's documentation, whereas on another game where the target is set to iOS 11, the Quick Help does point to the right place.
I don't want to change the target to a newer one because that would break compatibility with older phones. Is this a matter of hard-coding the Base SDK or something?
Edit:
I accepted the first answer as valid, but I thought I would write down some clarifications, just in case someone else gets stuck in something similar:
If you have updated your project to the latest Swift, the Base SDK should be the latest by default.
If you haven't, your old code will still compile. That's why func prefersHomeIndicatorAutoHidden() still works in my other project, since it used to be a function (https://stackoverflow.com/a/52387441/1765629) and I haven't updated that project to Swift 5.
The above is independent of the deployment target, so it seems I don't even need the #available in this case. I assume the value will be ignored in older iOS targets.
as #Starsky points out,
#available(iOS 11.0, *)
override var prefersHomeIndicatorAutoHidden: Bool {
return true
}
Background
I have a fairly detailed (around 2000 lines of swift code) automation framework built with Xcode 7.3 and Swift for our iOS app.
Up till a recent point, I was able to use lldb to build my framework i.e
insert breakpoint and run code up till that point
use po XCUIApplication().debugDescription and expr bla bla to build the logic
repeat
Problem
Pretty much all of a sudden, I now encounter the following error whenever running anything inside lldb's console:
(lldb) po XCUIApplication()
error: <EXPR>:2:1: error: 'XCUIApplication' is only available on iOS 9.0 or newer
XCUIApplication()
^
<EXPR>:2:1: note: add 'if #available' version check
XCUIApplication()
^
<EXPR>:2:1: note: add #available attribute to enclosing instance method
XCUIApplication()
^
<EXPR>:2:1: note: add #available attribute to enclosing extension
XCUIApplication()
^
<EXPR>:10:9: warning: initialization of variable '$__lldb_error_result' was never used; consider replacing with assignment to '_' or removing it
var $__lldb_error_result = __lldb_tmp_error
~~~~^~~~~~~~~~~~~~~~~~~~
Notes
Googling and research has not gotten me anywhere significant.
The one relevant thread I found was in the fastlane project. Unlike that comment, mine is a UI Test target.
Also, the test target's "iOS Deployment Target" is set to iOS 9.2 (in case that helps).
To the extent I remember, I haven't changed anything significantly in recent times.
My device is (and has always been) iOS 9+.
What could be going wrong?
Update 20 May 2016
Some exploration based on the answer below: https://stackoverflow.com/a/37335950/682912
The issue happens only on real devices. Simulators do not face this problem.
On real device (iPhone 6S+, iOS 9.2.1), I did a full reset of Content and Settings. This did not fix the issue.
This is a bug in the debug agent installed on your device. These are bound to the iOS version, so it probably happened when you upgraded your device. Anyway, please file a bug with http://bugreporter.apple.com.
If I'm right about the problem, it should only happen when debugging to the device, not on the simulator. That might allow you a temporary workaround till the bug gets fixed.
Double check your .xcconfig with your test target or any other means that may set your IPHONEOS_DEPLOYMENT_TARGET to lower than 9.0.
Since UITest is only available on iOS9.0 or later, change IPHONEOS_DEPLOYMENT_TARGET to 9.0+ should fix the issue.
The #available compiler check in Swift (introduced in Swift 2.0) doesn't seem to work with Target Membership.
For example, I have different targets in my project that are for iOS, watchOS, tvOS, OS X, etc. Some files are included in more than one target membership. I'm trying to do this:
if #available(iOS 8.0, *) {
locationManager.startUpdatingLocation()
} else if #available(watchOS 1.0, *) {
locationManager.requestLocation()
}
The error in Xcode says: 'startUpdatingLocation()' is unavailable. However, this file is common to both platforms and targets. Am I approaching this wrong? How can I mix platform code within the same file?
You can conditionally compile code for each platform, using the os() directive:
#if os(iOS)
if #available(iOS 8.0, *) {
locationManager.startUpdatingLocation()
}
#elseif os(watchOS)
locationManager.requestLocation()
#else
...
#endif
Valid arguments are OSX, iOS, watchOS, and tvOS.
This way, your common code which is used by more than one target will only contain compiled code specific to that build configuration.
For more information, see Build Configurations in Using Swift with Cocoa and Objective-C.