Jump to content
Sign in to follow this  

[iOS] Best way to keep compatible with older iOS versions

Recommended Posts

Hi there,


usually I don't care much about iOS versions, I would expect that those customers have the latest stuff always.
But I was facing the issue that an older iPHone 5S (iOS 10.3.4) cannot tested via TestFlight.
I see a message, similar to this



Of coarse I may use features that are probably not available in older IOS, but I'm asking myself in general what strategy would fit best,
to keep most apps as compatible as possible.
I don't really know if iOS 10 is still supported, but the platform status says so, that is will be down to iOS 10.3 (never tested this).


Its not easy to find out which features are depreceated or changed in each version, or is there maybe a good history of versions in the web ?
I have never seen any for iOS.


Currently I'm trying to encapsule simple features, as best as possible, so that I can test and enable/disable them separately (like notification, tts, sensors, location, etc..).

What I did not incuded yet is a kind of "version control" for each feature, I think about e.g. certain features may have varying permisson models and behaviours,
but that could be still acceptable for basic functionality of the app.
Each feature could behave slightly different within different versions, but the app wouldn't crash right away, instead notifies gracefully.

Probably this would be a little too difficult for abstraction, but I hope that breaking changes doesn't occur too often.
I think XCode does a very good job in helping the developer in these cases, and to fix issues automatically, would like to have such XCode knowledgebase in my code too :classic_biggrin:.


If there are some interesting links about such abstraction, I would be happy to get some feedback.


Edited by Rollo62

Share this post

Link to post

No ideas :classic_sad:


I could think of an interface system like FMX.Platform, to separate all features well.
So that I could have multiple implementations, could override to fix something on the fly, and my features
could be created by requesting the availability first.

  LScreenService: IFMXScreenService;
  LScreenSize: TPoint;
  LMyService: IFMXMyService;
  if TPlatformServices.Current.SupportsPlatformService(
       IFMXScreenService, IInterface(LScreenService)) then
    LScreenSize := LScreenService.GetScreenSize.Round;

  if TPlatformServices.Current.SupportsPlatformService(
       IFMXMyService, IInterface(LMyService)) then //<= This checks if a feature is generally available (also kinda OS dependent)

    if LMyService.CanUseMyFull then  // <= This could check if to what degree the feature is available at current OS-version
       LMyService.UseMyFull;  // <== and use it fully if available
    if LMyService.CanUseMyPartly then  // <= This could check if to what degree the feature is available at current OS-version
       LMyService.UseMyPartly;  // <== and use it partly if available

Would that be the perfect pattern to abstract such complex features also on different platforms and versions ?

Mainly beauty may arise from a perfect naming system.


Ideally I don't want to deal with version changes any longer, but simply want to use what is possily, to avoid crashes.

The version requests are nicely hidden inside the services.


But is this the best approach, is this really efficient and fits all needs ?
Embarcadero decided for this to use it at the core, so it shouldn't be too bad, I'M not sure if there are better patterns available.


I could also think about a messaging system, where all components communicate via publish/subscribe, which would ensure a very good separation, but that is not as easy to use as the FMX.Platform style.


Another way could be simply by deriving features from a base class, to make use of normal class inheritence.


Probably all different ways tend up to get messy soon, do I oversee someting ?




Edited by Rollo62

Share this post

Link to post

There's no "easy" way to cater for older versions, whether it's iOS, macOS or Android. The best you can do is check the API documentation for which version the methods were introduced (or removed) and use TOSVersion.Check to determine whether the code is relevant and can be called, and branch to another part of the code if you need to cater for lower versions. There's a bunch of examples of TOSVersion.Check being used in the FMX code, so you could refer to them.

Share this post

Link to post

I wanted to build a "system" or "pattern" that better could encapsulate such changes from the interface side.

Of coarse the internal implementations may look totally different, and TOSVersion would help much.
My goal is that from the interface side all this complexity is hidden.


Not sure howto hide such complexits best.

Personally I like the CanUse, DoUse, TryUse patterns, but they also need some kind of conditions when not necessary.

Probably there are better concepts out there.


I'm also not sure if enhancing the FMX.Platform system is a good idea, since this is the domain of Embarcadero,
but I think doing so would keep the same pattern also for my own interfaces.


Another possibility is simply "fixing" broken classes, to get the desired behaviour, e.g. by interposer classes.


There are also people who like to completely replace the existing interfaces, by some own, well controlled interfaces,
like maybe the TMS FNC did (I don'T really know this, but I think that will replace all existing TButton, TEdit, etc.).


Maybe ways, but what will be the "golden way" (if there is any) ?



Edited by Rollo62

Share this post

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this