3

So with each new OS a bunch of methods are declared deprecated. The strange thing for me is that if I want to still support iOS5 AND iOS6 I have to use BOTH the deprecated and the replacement method, like with UILabel's minimumScaleFactor over minimumFontSize.

If I replace myLabel.minimumFontSize to myLabel.minimumScaleFactor than my app will come crashing down in iOS5.

So I use an if with -respondsToSelector: to find out whether the OS is 5 or 6 and use minimumScaleFactor or minimumFontSize accordingly.

The problem is that I might have to write a bunch of ifs and respondsToSelectors in my code and that feels dumb.

Is there a better way to deal with deprecations?

Zoltán Matók
  • 3,923
  • 2
  • 33
  • 64

5 Answers5

6

I create function which i can use in any ios:

void AbsSdk30_upg60_UILabel_setMinimumScaleFactor(UILabel * label, CGFloat minimumScaleFactor) {
    if ([label respondsToSelector: @selector(setMinimumScaleFactor:)]) {
        [label setMinimumScaleFactor: minimumScaleFactor];
    }
    else {
        const CGFloat curFontSize = label.font.pointSize;
        const CGFloat fontSize = (0.0 == curFontSize) ? [UIFont labelFontSize] : curFontSize;
        [label setMinimumFontSize: fontSize * minimumScaleFactor];
    }
}
Maxim Kholyavkin
  • 4,463
  • 2
  • 37
  • 82
2

Language independend solution: get the OS at the start of your app and set a global variable. Then, when neede query the variable for the OS version. You could do it in a case/switch statement to allow for easy extensability if changes in future versions occur.

Pseudo code:

switch iOSversion
    case < 6
        dothis
        break
    case <7
        dothat
        break
    case >7
        OS not supported ;)

Technically it is the same thing as with the IFs, but your source would be shorter and more structured plus you don't have to query the OS version everytime, but once at the start of your app.

LuigiEdlCarno
  • 2,410
  • 2
  • 21
  • 37
  • 3
    I suspect that "OS not supported" logic like this is what breaks some applications in new operating systems. The developer forbids the software to work on a later version without waiting to discover what the incompatability - potentially none - would be. – Iain Samuel McLean Elder Sep 28 '12 at 15:38
  • 1
    You may be right, though it may be better this way, than for the developer allow for any OS version before he is certain, that his code won't break anything on the new system. – LuigiEdlCarno Oct 15 '12 at 06:46
  • You are right: it saves the developer from unintentionally breaking future systems. If you can't test it (because it doesn't exist yet), then you can't support it (yet). – Iain Samuel McLean Elder Oct 16 '12 at 10:43
1

For that you should put the deployment target minimum. So that if you run your application.At that time it will not give you deprecated errors.And also you don't need to write the if s and respondsToSelectors in your code. you can put your deployment target to ios 5.0 or 5.1 I think it will work for you. And if you want your deployment target 6.0 then there will be a another method which can replace that deprecated method.

puneet kathuria
  • 720
  • 1
  • 7
  • 10
1

I treat 'deprecated' as a warning that a method may go away at some point in the future, not that it has to be replaced now. Rather than complicating the code for current builds I leave myself comments about what to change when I drop support for certain older versions.

Except for things that stop working in a new release, I don't #ifdef by versions.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
0

Add a category to UILabel like this in a .h file or in .h and .m files where the .h file will be imported by the code that uses it:

@interface UILabel (UILabelCategory)

+ (CGFloat)minimumLabelFontSize;
- (void)adjustsFontSizeToFitWidthWithMinimumFontSize:(CGFloat)fontSize;

@end

@implementation UILabel (UILabelCategory)

+ (CGFloat)minimumLabelFontSize // class method that returns a default minimum font size
{
    return 11;
}

- (void)adjustsFontSizeToFitWidthWithMinimumFontSize:(CGFloat)fontSize
{
    if ([self respondsToSelector: @selector(setMinimumScaleFactor:)])
    {
        CGFloat currentFontSize = self.font.pointSize == 0 ? [UIFont labelFontSize] : self.font.pointSize;
        [self setMinimumScaleFactor:fontSize / currentFontSize];
    }
    else
    {
        [self setMinimumFontSize:fontSize]; // deprecated, only use on iOS's that don't support setMinimumScaleFactor
    }
    [self setAdjustsFontSizeToFitWidth:YES];
}

@end

And then call the UILabel extension like this from multiple places in your code: (assuming that you have a UILabel object called _instructions and that you import the file that implements the UILabelCategory extension)

[_instructions adjustsFontSizeToFitWidthWithMinimumFontSize:[UILabel minimumLabelFontSize]];

or like this:

[_instructions adjustsFontSizeToFitWidthWithMinimumFontSize:14];

Note: remember that on iOS 6 and prior the setMinimumFontSize only works if you also set the number of lines to 1 like this:

[_instructions setNumberOfLines:1]; // on iOS6 and earlier the AdjustsFontSizeToFitWidth property is only effective if the numberOfLines is 1
Richie Hyatt
  • 2,244
  • 2
  • 21
  • 14