Easily Overlooked New Features in iOS 7

Check out this list of easily overlooked features in iOS 7 – there will probably be a few you’ve never heard of! By .

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

10. UIButtonTypeRoundRect has been deprecated in favor of UIButtonTypeSystem

Good bye, old friend.

Good bye, old friend.

Good bye, old friend.

One of your old friends from your beginnings in iOS development (and a popular control in many rapid prototypes) is now defunct: UIButtonTypeRoundRect has been replaced by a new UIButtonTypeSystem. Excuse the dust, but progress we must! :]

The Really Good News: New Features

What would a major release of iOS be without some new features? These new features have largely been well-received in the iOS community, and you may even find some novel ways to integrate them in your own apps!

11. Check which wireless routes are available

The ability to customize a video player (and friends) has evolved throughout the past few iOS versions. As an example, prior to iOS 6 you couldn’t change the AirPlay icon on a MPVolumeView.

In iOS 7, you’re finally able to know if a remote device is available via AirPlay, Bluetooth, or some other wireless mechanism. This allows your app to behave appropriately, such as hiding an AirPlay icon when that service isn’t available on other devices.

The following two new properties and notifications have been added to MPVolumeView:

@property (nonatomic, readonly) BOOL wirelessRoutesAvailable; // is there a route that the device can connect to?
@property (nonatomic, readonly) BOOL wirelessRouteActive; // is the device currently connected?

NSString *const MPVolumeViewWirelessRoutesAvailableDidChangeNotification;
NSString *const MPVolumeViewWirelessRouteActiveDidChangeNotification;

12. Get information about the cellular radio signal

Prior to iOS 7, detecting if a device was connected via WWAN or Wifi was possible using Reachability. iOS 7 takes it a step further and tells you exactly which kind of cell radio networking the device is connected to, such as Edge, HSDPA or LTE. This can be extremely useful to tailor the user experience to the speed of the network they are connected to, by making fewer network requests or downloading lower resolution images as appropriate.

This feature is part of the little known CTTelephonyNetworkInfo, which is part of the CoreTelephony framework. iOS 7 also added the currentRadioAccessTechnology property to this class, as well as the notification CTRadioAccessTechnologyDidChangeNotification. There’s some new string constants as well to define the possible values such as CTRadioAccessTechnologyLTE.

Here’s how you’d use this new feature in your app delegate:


@import CoreTelephony.CTTelephonyNetworkInfo; // new modules syntax!

@interface AppDelegate () 
// we need to keep a reference to the CTTelephonyNetworkInfo object, otherwise the notifications won't be fired!
@property (nonatomic, strong) CTTelephonyNetworkInfo *networkInfo;

@end

@implementation ViewController 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // whatever stuff your method does...

  self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
  NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];

  // whatever stuff your method does...
}

- (void)radioAccessChanged {
  NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology);
}

@end
Note: Take a look at CTTelephonyNetworkInfo.h to discover the other string constants for other wireless networks. As a note, currentRadioAccessTechnology will return nil if the device is currently not connected to a radio tower.

13. Sync passwords between user’s devices via iCloud

iOS 7 and Mavericks introduced iCloud Keychain to provide synchronization of passwords and other sensitive data via iCloud. This feature is available to developers via the kSecAttrSynchronizable key in the Keychain attributes dictionary.

Since dealing directly with the Keychain is often a real pain, wrapper libraries provide an easy way to work with the Keychain – without the sharp edges. The SSKeychain wrapper library is probably the best-known one out there, and as an added bonus, it currently supports iCloud sync out of the box.

The code snippet below shows how you’d use SSKeychain:

#import <SSKeychain.h>

- (BOOL)saveCredentials:(NSError **)error {
    SSKeychainQuery *query = [[SSKeychainQuery alloc] init];
    query.password = @"MySecretPassword";
    query.service = @"MyAwesomeService";
    query.account = @"John Doe";
    query.synchronizable = YES;
    return [query save:&error];
}

- (NSString *)savedPassword:(NSError **)error {
    SSKeychainQuery *query = [[SSKeychainQuery alloc] init];
    query.service = @"MyAwesomeService";
    query.account = @"John Doe";
    query.synchronizable = YES;
    query.password = nil;
    if ([query fetch:&error]) {
        return query.password;
    }
    return nil;
}

Don’t forget that CocoaPods is a quick and easy way to install SSKeychain.

14. Display HTML with NSAttributedString

Using Webviews in your apps can be frustrating at times; even if you’re only displaying a small amount of HTML content, Webviews can consume a lot of memory. iOS 7 makes this a lot easier, as you can create an NSAttributedString from HTML with a few lines of code, as such:

NSString *html = @"<bold>Wow!</bold> Now <em>iOS</em> can create <h3>NSAttributedString</h3> from HTMLs!";
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};

NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:nil error:nil];

Now you’re free to use the NSAttributedString on any UIKit object, such as a UILabel or a UITextField, as in the following code:

Note: NSHTMLTextDocumentType is just one of the possible values for the NSDocumentTypeDocumentAttribute key. You can also use NSPlainTextDocumentType, NSRTFTextDocumentType or NSRTFDTextDocumentType.

You can also create an HTML string from an NSAttributedString as shown below:

NSAttributedString *attrString; // from previous code
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};

NSData *htmlData = [attrString dataFromRange:NSMakeRange(0, [attrString length]) documentAttributes:options error:nil];
NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];

That should encourage you to use HTML more freely in your applications! You can learn more about attributed strings in iOS 6 by Tutorials.

15. Use native Base64

Base64 is a popular way to represent binary data using ASCII characters. Until now, developers were forced to use one of the many open source alternatives to encode and decode the Base64 content.

iOS 7 introduces the following four new NSData methods to manipulate Base64-encoded data:

// From NSData.h

/* Create an NSData from a Base-64 encoded NSString using the given options. By default, returns nil when the input is not recognized as valid Base-64.
*/
- (id)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options;

/* Create a Base-64 encoded NSString from the receiver's contents using the given options.
*/
- (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options;

/* Create an NSData from a Base-64, UTF-8 encoded NSData. By default, returns nil when the input is not recognized as valid Base-64.
*/
- (id)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options;

/* Create a Base-64, UTF-8 encoded NSData from the receiver's contents using the given options.
*/
- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options;

These methods let you easily convert NSData objects to and from Base64, as shown in the following example:

NSData* sampleData = [@"Some sample data" dataUsingEncoding:NSUTF8StringEncoding];
    
NSString * base64String = [sampleData base64EncodedStringWithOptions:0];
NSLog(@"Base64-encoded string is %@", base64String); // prints "U29tZSBzYW1wbGUgZGF0YQ=="
    
NSData* dataFromString = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
NSLog(@"String is %@",[NSString stringWithUTF8String:[dataFromString bytes]]); // prints "String is Some sample data"

If you need to support iOS 6 or earlier, you can use the following two deprecated methods that are now public:

/* These methods first appeared in NSData.h on OS X 10.9 and iOS 7.0. They are deprecated in the same releases in favor of the methods in the <code>NSDataBase64Encoding</code> category. However, these methods have existed for several releases, so they may be used for applications targeting releases prior to OS X 10.9 and iOS 7.0.
*/
- (id)initWithBase64Encoding:(NSString *)base64String;
- (NSString *)base64Encoding;