How to check latest version of iOS in Swift without using #available? - ios

How can we check if the OS running on iPhone is the latest one. Is there any API for that?
For example, user is using iOS 14.6, so I want to know if its the latest version that he is using
I know this code is for checking, what OS user is having. This is not the answer at all. Please read the question before closing
if (#available(iOS 14.6, *)) {
// Use iOS 11 APIs.
} else {
// Alternative code for earlier versions of iOS.
}

No there is no way except available only if you created a personal Api to provide this info for your app automatically when opened

Related

iOS: Concurrency is only available in iOS 15.0.0 or newer in protocol

I have an app which deployment target is iOS 12.1, with many protocols defining functions with completion handlers, i.e.
protocol P {
func f(_ completion: #escaping: (String) -> Void)
}
I would like to replace all these with the new async/await iOS 15 syntax, for a better code readability:
protocol P {
func f() async -> String
}
But when doing so, I get the error:
Concurrency is only available in iOS 15.0.0 or newer
What is a good solution for this, considering that I just cannot switch the deployment target from 12.1 to 15.0?
Thank you for your help
For other people who are looking facing this issue on 15.0 target.
This is likely related to your XCode version, you need to be have minimum XCode 13.2 or later to compile code which uses Swift Concurrency on versions older than iOS 15.
The short answer is "there is currently no solution." If you want your apps to run on iOS 12 and earlier, you can't use the async/await calls, unless you want to write 2 versions of all your async code, one that runs on iOS < 15, and the other that runs on iOS ≥ 15.
As George mentions in his comment, Apple is trying to figure out how to "back-depoloy" async/await support. If they are able to do that, you will be able to use the modern approach with older versions, but I would bet Apple will not go back as far as iOS 12.
Edit:
See Bradley's comment below. The best you will get is async/await support in iOS 13, if Apple is able to pull that off. From the link Bradley posted, iOS 12 definitely won't be supported.

How to resolve 'init(proximityUUID:identifier:)' was deprecated in iOS 13.0 for iBeacon

I want to receive RSSI of iBeacon on my iOS application this code can run on iOS12. Now I have updated to iOS 13 this code can't run.
and alert
'init(proximityUUID:identifier:)' was deprecated in iOS 13.0
'startRangingBeacons(in:)' was deprecated in iOS 13.0
'stopRangingBeacons(in:)' was deprecated in iOS 13.0
How to fix this problem?
If you look at the documentation for the method your are using it tells you that it was deprecated in iOS 13 and also tells you what to use instead.
In case the link breaks, this is the alternative option:
init(uuid:major:minor:identifier:)
Check the documentation for the other methods and it will tell you which alternatives to use.
Now.. to configure your app to switch between methods based on the iOS version you can use an #available check..
if #available(iOS 13, *) {
// use the shiny new one
} else {
// use the old one
}

iOS 13 - FileManager url(forPublishingUbiquitousItemAt:expiration:) not working anymore

I've developed an iOS app that uses the url(forPublishingUbiquitousItemAt:expiration:) method of Apple's FileManager class. Starting with the first Beta of iOS 13 this function stopped working and now it throws an error, stating "This code has been removed. You should switch off of this SPI". But I can't find anything related to this function neither in the release notes of iOS nor in the documentation for this function, and it even states there that it would be supported on Mac Catalyst 13.0+.
This also has nothing to do with Xcode 10 and 11, as it occurs when the app is built using either one of those versions.
Does anyone of you know more about that? It would be great to get new information on that.
Thanks,
Fabian.
This is fixed in iOS 13 beta 6. Updated today and this error magically disappeared!
Had my mind blown when I saw this error message.

Can I use "uppercaseString" in an app targeting 8.0? Is it safe pre iOS 8.3?

I'm using the built in string method uppercaseString, like this:
let capitalLetters = myString.uppercaseString
The documentation tells this for availability:
iOS (8.3 and later)
However, Xcode is not giving a compiler error, with the if #available recommendation, i.e:
if #available(iOS 8.3, *) {
} else {
}
My question is simple. Can I use this method in an app targeting 8.0? I cannot test it on a device with this version because I don't have one. And the simulator I have is 8.4.
From Apple's documentation:
var uppercaseString: String { get }
Available in iOS 2.0 and later.
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/occ/instm/NSString/uppercaseString
Sometimes xcode shows you wrong availability versions (since swift came out). If sometimes you aren't sure about the availability - check it online.
PS: You can download simulators for which version you want

How to define code for different iOS versions

I am working on an iOS app. I want it to support iOS 7 and 8. It is going pretty nicely, however there are lots of different parts of the app which use Apple APIs. Some of these APIs work in both iOS 8 and 7. However, some of them are deprecated in iOS 8. So I therefore went to the Apple developer site to see what to replace them with (new methods/etc....).
However, I now have the problem that the app will work on iOS 8 fine, but certain parts of it don't work properly on iOS 7 as I'm trying to use an iOS 8 API...... (lol).
So I just wanted to know, what is the best way to implement code which works on iOS 8 and 7. I had a few ideas (below), but I'm not sure which is best:
IDEA 1
Whenever I have code which doesn't work on both OS's, I use an if function (which calls a macro) like so:
if (SYSTEM_VERSION_LESS_THAN(#"8.0")) {
// iOS 7 device. Use iOS 7 apis.
}
else {
// iOS 8 (or higher) - use iOS 8 apis.
}
IDEA 2
I was thinking about using ifdef definitions all around the app like so:
#ifdef __IPHONE_8_0
// iOS 8 code here....
#else
// iOS 7 code here....
#endif
Which way is better? I would have thought that the second idea is much faster and uses less resources right?
Or are both my ideas rubbish? Is there a much better way about solving this problem?
Thanks for your time, Dan.
I don't suggest checking the Version and writing code based on that. Instead you need to check whether that API is available or not.
For checking a class available or not:
Class checkClass = NSClassFromString(#"CheckingClass");
if (checkClass)
{
// Available
}
else
{
// Not Available
}
If you need to check a feature/function available;
if ([checkClass respondsToSelector:#selector(yourMethod:)])
{
// Feature/ Method Available
}
else
{
// Feature/ Method Not Available
}
NOTE:
Deprecated API's doesn't mean that you shouldn't use that in current version. It means, it won't work from next version onwards, and only work till current version.
The ifdef-way won't work, because preprocessor statements are evaluated at compile-time; but only at runtime we know which ios-version we have to deal with.
You would use macros for example if you wanted to support Mac OS X and iOS with the same code, because you know at compile-time if the binary will be for Mac OS or iOS.
So you need in this case approach 1 - or, even better, you should use respondsToSelector: to check for availability instead of testing the iOS version if possible.
However, because you are only dealing with deprecation warnings, you don't have to do anything and should simply continue using the deprecated APIs until the app no longer needs to support ios7.

Resources