Novice developers: the story of one bug, or why you can not like the new versions of iOS



    More recently, Apple introduced a beta of the new version of iOS, which, as usual, contains many "tasty" features. But along with the pleasant one, the question arises: how will already released applications work on the new version of iOS? In general, the theme of the work of old applications on the new version of the mobile OS is rarely mentioned. Here, on Habr, I met only one article "Backward compatibility in iOS SDK" . I would like to supplement it with my story.

    In the text under the cut - a brief description of the "rake" that I happened to step upon when preparing the new version of Parallels Mobile with iOS 5 support, and ways to get around this rake. We will also see an example of Apple’s “special” attitude to the topic of backward compatibility in the iOS SDK, and a couple of tips on how to minimize problems when switching to new versions of the mobile OS.



    Investigation of a bug often begins with its localization in time, that is, with an understanding of when (and also by whom and why) it was admitted. To do this, a search is made for the latest changes related to the problem place. Usually it quickly becomes clear who is to blame, and there is not much to understand what to do. But what if an error occurs in old code that no one has touched since the last released version, in which, of course, everything works?

    The situation is not simple, and there is no single solution. Therefore, we will consider an example of a real problem that we encountered when releasing the Parallels Mobile update: when the application starts (and when it returns from the background mode), the state of the UISegmentedControl element does not coincide with the contents of the page. The situation is shown in the figure below:



    If you switch the tabs of the UISegmentedControl by hand, and not set the desired programmatically, everything works correctly.

    The study of all the components that in one way or another can affect the UISegmentedControl and the content of the page ended with nothing: it turned out that no changes to the project were associated with the code that provided changes to the content of the page depending on the state of the UISegmentedControl. Further experiments showed that the version compiled from the same sources as the application in the App Store also contains the mentioned bug. But how can a program compiled from the same sources work differently on the same version of iOS? (To complete the experiment, application tests: the old version from the App Store and the new rebuilt version were carried out on the same iOS device).

    We’ll start our investigation of a global problem with a specific task: we’ll take a closer look at UISegmentedControl. To track tab switching, you need to register the UIControlEventValueChanged event handler as follows:

    [self addTarget:self action:@selector(didValueChanged:) forControlEvents:UIControlEventValueChanged];
    

    The didValueChanged handler function changes the contents of the page in accordance with the state of the UISegmentedControl.

    Further study of this UI Control in the Apple documentation showed that, starting with iOS 5.0, programmatic state change no longer generates the UIControlEventValueChanged event. This means that in new versions of iOS, in order to change the content of the page, it is necessary to explicitly generate this event if the segment selection is done not by the user, but in the application code.

    An event can be generated immediately after setting the selected segment number and it is better to pre-check the iOS version, otherwise on older versions of the operating system the UIControlEventValueChanged event will be generated twice:

    [self setSelectedSegmentIndex:ind];
    if (SYSTEM_VERSION >= 5.0)
        [self sendActionsForControlEvents: UIControlEventValueChanged];
    

    The presented code solves the problem, but leaves a very important question open: why does the version from the App Store work the same way on the new iOS 5.1?

    Answer from Apple documentation : “As a backward-compatibility mechanism, Apple frameworks sometimes check for the version of the SDK an application is built against, and, if it is an older SDK, modify the behavior for compatibility. This is done in cases where Apple predicts or discovers compatibility problems. ”

    Like this! Trying to guess whether Apple will make the appropriate changes to the new version of iOS so
    that your applications work the same way is very similar to Russian roulette. Therefore, to avoid mysterious problems, follow three simple rules:
    1. carefully study the changes in the iOS API , especially if a major update of the operating system comes out;
    2. conduct full regression testing when switching to the new iOS SDK;
    3. expand the set of regression tests. This will allow you to detect a problem when switching to a new version of iOS, which means that you will narrow down your search for solutions and reduce the time needed to solve the problem.

    Well, in conclusion, I must say that Apple is one of the few vendors that allow themselves to change the behavior of platform elements (UI Controls, functions, etc.) between versions of the platform. Usually, the functionality of existing components is expanded: new parameters appear for more flexible control of the element. Or new elements with different default behavior appear, and old components are deprecated and removed in new versions of the platform. Why Apple sometimes chooses the path of revolution rather than evolution is not clear, but all that remains for us is to switch to Android to minimize our problems when switching to the new iOS.

    Also popular now: