What's New in iOS 9 and Swift 2.0: Stack Views, Distribution, and Error Handling
Apple has recently released the next iteration of iOS, and we're pleased to announce that our native Xuni iOS controls support iOS 9 and XCode 7. Several new features in this release will certainly be of interest to any iOS developer, and even those coming from C# and Java. Today I'll highlight a few of the most important additions, and how they can be used with Xuni to facilitate better application development.
Stack Views: Automatic Layouts
Stack Views are containers that allow controls to be automatically laid out vertically or horizontally, and are very similar to Linear Layouts in Android development or Stack Layouts in Xamarin.Forms. This is my favorite addition to iOS 9, since laying out Views and Subviews has historically required a lot of effort. With Stack Views, the process has been streamlined by a large margin. Rather than writing code or setting constraints for every View to ensure appropriate sizing and positioning, we can now configure a containing Stack View to take care of much of this for us. Storyboard design can now be simplified to:
- Add a Stack View to a View Controller Scene
- Set any constraints on the Stack View
- Set Properties for Alignment, Distribution (which sizes the controls), and Spacing (padding between controls)
- Drag and drop your controls into the Stack View
Distribution: Controlling Auto-Sizing
The distribution property gives you several options for how the Stack View will resize its arranged views to fill any available space. There are several different options here, both how the stack view behaves (which is based on the distribution property), and how the arranged views will grow or shrink (which is based on the content hugging priority and content compression resistance priority). I'll briefly cover them here as there's some nuance in using the correct one for your application.
- Fill fills all the available space along the axis of the Stack View. If there is not enough space, it shrinks views based on their compression resistance priority. If there's extra space, it grows views based on their content-hugging priority.
- Fill Equally sizes all of the views equally to fill up the available space along the axis of the Stack View.
- Fill Proportionally sizes all of the views to fill up the available space along the axis of the Stack View based on their intrinsic content size.
- Equal Spacing fills all the available space along the axis of the Stack View. If there isn't enough space, it shrinks views based on their compression resistance priority. If there's extra space, it pads the spacing between the views evenly.
- Equal Centering attempts to position the views so that they have an equal center to center spacing along the axis of the Stack View. If there isn't enough space, it shrinks views until it reaches the minimum spacing defined in the spacing property. If the view still don't have enough space, it shrinks views based on their compression resistance priority.
Apple has provided some documentation with images that really highlight the differences in behavior. They can very dramatically alter your application layout. For example, my sample application with:
Fill
Fill Equally
I've designed around using the Fill distribution in this case which best suits the material, though your mileage will vary depending on your content. This makes iOS interface design much more straightforward, and makes the process a lot easier for those new to native iOS development but familiar with Android development or Xamarin.Forms. You can also nest Stack Views to build advanced designs that previously would have required a large amount of time. Xuni development is now streamlined, as well, since this takes much of the effort out of positioning and sizing the controls, and it allows you to focus on making your application look and feel good. You can refer to my previous blog post for using Xuni with iOS Storyboards as a getting started point.
Swift 2.0
Apple has added several significant features to Swift which should appeal to anyone either considering or actively developing for iOS. Some of the features are common to other languages, and their previous absence may have discouraged some from venturing too deeply into Swift development. I’ll mostly examine Swift’s new error handling mechanism as it has the most direct applications for use with Xuni, but Apple's Swift blog has more information.
Error Handling with Do/Catch
One of the biggest omissions in Swift up to this point has been the lack of a built-in error-handling mechanism. Both Java and C# give developers the ability to use Try/Catch/Finally blocks to handle exceptions, and now something similar has been added for Swift. Apple has provided a Try/Catch mechanism with slightly different syntax which they call Do\Catch. The error pattern follows this pattern:
- Do: Code that your application will try to execute. The try keyword prefaces the method call that could throw an error.
- Catch: Errors that you defined to catch and how they’re handled
- Defer: Code that executes no matter what (much like Finally in other languages). This allows you to ensure that something as simple an open File is closed appropriately if an error occurs without any extra conditional logic.
The errors that are caught are defined by the developer as an enum in code. For example, we may want to verify that the integer value that a user inputs is a positive value and not equal to zero. We can define an enum as follows:
enum Error: ErrorType{
case lessThanZero
case equalsZero
}
Now, we'll want to indicate that our method can throw an error, so we add the throw keyword to its declaration:
class func getCustomerData(total: Int) throws -> NSMutableArray{...}
When we execute the function in a do/catch block, we can add checks to see which error was actually thrown by the method:
do{
//this is the code you will try to execute
d = try CustomerData.getCustomerData(rowsToReturn)
}
catch CustomerData.Error.equalsZero{
//a caught error
inputField.text = "Please enter a value greater than zero"
}
catch CustomerData.Error.lessThanZero{
//another caught error
inputField.text = "Please enter a postive value greater than zero"
}
catch{
//a catch all
inputField.text = "Something unpredicted happened"
}
defer{
//code that executes no matter what
}
The last thing that we need to do is explicitly throw these errors in our method. Apple has once again provided another change to make this a clearer process.
Guard: Demonstrate Explicit Intent
Methods / Functions can be defined to throw specific errors based on certain conditions, and Apple has provided a guard keyword to demonstrate explicit intent. The guard keyword is no different functionally than an if else statement, but it does provide clear intent when you’re performing error checking in code.
guard total > 0 else {throw Error.lessThanZero}
guard total != 0 else {throw Error.equalsZero}
This syntax clearly alerts other developers of your intention to throw errors.
Wrap Up
In closing, Swift is a rapidly maturing language, and it's good to see Apple filling in some gaps to bring parity with other platforms in previously lacking areas. Xuni provides an easy mechanism for enhancing your iOS applications, and provides a common object model between platforms. Now more than ever Xuni and iOS bring together the ability to develop great applications with features to ease development for those new to the platform.