Swift 4 Is Here: A Roundup Of The New Features

By | January 3, 2018
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Apple’s Swift programming language is showing signs of recovery, after going into an absolute freefall between July and November 2017. The language, which had broken into the top-ten list on the TIOBE Index for the first time in March, had 1.566% ratings in early-December (rank – 11) – slightly up from the ratings the previous month. Interestingly though, there has been a 0.57% fall in the ratings of Swift on a YoY basis (2.134% in December 2016). The fourth iteration of the language was released by Apple last September – with many experts predicting that it will help in shoring up the adoption rates of Swift. Over here, we take a look at some of the interesting new features in Swift 4:

  1. Migrating to Swift 4

    The latest version of the programming language has been launched along with Xcode 9 (Xcode is the IDE for coding apps on the Apple platform). Xcode 9 offers full support for Swift 4 along with the transitional Swift 3.2. This, in turn, eases the process of migrating any code written in version 3.x to the newest syntax. For projects that have more than one target, different versions of Swift can be defined for each target. The built-in Swift conversion tool ensures fast and secure processing of the migration – and developers might have to recompile their dependencies in Xcode 9. Once the target(s) in the project have been selected, the conversion can be initiated by clicking on ‘Edit → Convert → To Current Swift Syntax…’.

Note: Since the Swift Package Manager is still not quite robust enough, coders generally prefer using the CocoaPods dependency manager.

  1. Key value coding with keypaths

    Dynamic referencing of properties with the help of ‘keypaths’ is one of the most convenient features in Objective-C. However, till now – creating such references in Swift was not possible (users could create references to methods, since functions in Swift have ‘first-class’ type status). This issue has been resolved in the new version of the language. Now, there are keypaths that serve as ‘uninvoked references’ to properties in the code. For getting updated values, this referencing keypath has to be called/invoked later (after specifying it). On the other hand, the current value of the property at any point can be obtained by invoking the reference at any time. In Objective-C, coders often ran into troubles with the strings and arrays – and that problem is also tackled effectively by Swift 4, thanks to the ‘strongly typed’ keypaths in the latter. In future versions of the language, runtime creation of keypaths should also become available.

Note: With keypaths, developers no longer have to access with the underlying property values. The properties can be referenced directly.

  1. One-sided ranges in Swift 4

    This feature has been implemented in a bid to reduce the verbosity of the language, while performing slicing up to/from an index within a collection. To ease out the process of creating methods for different ranges, there is a new method called ‘RangeExpression’ – and the ‘missing’ side of the one-sided range is inferred to be the prefix or the suffix. Pattern matching is a classic use case where these one-sided ranges can be very useful (checking for conditions within a range). App-makers also have the option of defining ‘infinite sequences’ with a countable start index. The ‘RangeExpression’ protocol controls all the ranges in the code. If there are overloads that assume values other than ‘Range’ – they can also be quickly converted to generic methods that conform to ‘RangeExpression’.

Note: There are no resilience or compatibility consequences of using the one-sided ranges. This is because of the purely additive nature of the new types/operators.

  1. Arrival of the ‘Codable’ protocol

    Probably the most important new feature in the latest version of Swift. Custom data types might have to be serialized/deserialized at any time – and doing that wasn’t the easiest challenge in Swift 3.x. Developers had to either use classes (manual encoding/decoding required), or work with value types (which do not work well with NSCoding and other APIs in Obj-C). The ‘struct Language: Codable {  ’ line in Swift 4 offers a nice and easy alternative for these tasks. The codes for serialization are now auto-generated by the compiler (even for serializing to JSON). All the values/properties contained in the data types are encoded by the protocol – and ‘data’ objects can be converted back into strings (decoding) as well. It is also possible to support either encoding or decoding separately, in the following manner:

Struct EncodableTypename: Encodable { . . . }

JSONEncoder (JSONDecoder) and its corresponding method has to be called to encode (decode) anything. The Codable protocol includes both encoding and decoding capabilities.

Note: In Swift, both encoding and decoding are marked as ‘throws’. ‘Codable’ is a highly flexible protocol, and can be implemented in different ways (apart from the default implementation).

  1. Writing multi-line strings

    Adding multi-line strings in programs has become easier than ever, with the ‘multi-line string literals’ in Swift 4. Strings with text in any format (HTML, JSON) can be pasted without risks of value losses – and there is no need for any escaping either (as was required in earlier versions). The syntax is simple enough – a multi-line string literal has to start with 3 double quotes ( “ “ “ ), the string has to be pasted from the next line, and the literal has to close with another 3 double quotes on the following line (after the string ends). There are no limits on the length of the string that can be interpolated like this – and line breaks, variables and quote marks can be included too. The readability of long strings also gets a boost with these multi-line string literals.

Note: By putting backslashes at the end of lines, newlines can be escaped in these multi-line literals.

  1. Improvements in the Package Manager

    Ever since the launch of Swift 3 last year, there have been clamors among developers for a better, more flexible Swift Package Manager. While the latter is still not as resourceful as it might be, the Package Manager in Swift 4 does have certain significant improvements. Products can be built as libraries or as executables, there are new conventions that have to be used to declare targets, while the manifest API has undergone a revamp as well. A developer-friendly ‘dependency resolution’ feature has replaced the ‘pin mechanism’ of Swift 3.1. More changes in the Package Manager are expected in Swift 5 and later versions.

Note: The Swift Package Manager now also has built-in support for C and C++ languages. There is also a new ‘run command’ for building/running executables in the code.

  1. Smoother access control

    For all its other merits, the access modifier in Swift 3 (‘fileprivate’) was a pain point. This mechanism allowed other files easy access to members – with access being shared for type members located in the same file. The alternative was to use ‘private’ – but that did not work in cases where certain types did not have access to the required members. In an ideal scenario, ‘fileprivate’ should be used very sparingly, while ‘private’ should be used inside the member(s). In Swift 4, it is finally possible to have a type and its extension, and share the access control between them (of course, this functionality is valid only when the type and the extension are in a single source file). In essence, developers can finally use ‘fileprivate’ in the manner it was always supposed to be used.

Note: Coding in Swift typically calls for the creation of logical groups, with the help of code-breaking with extensions. ‘fileprivate’ is important for the purpose.

  1. Revisions in string operations

    Initially a feature of Swift, the need for Strings conforming with ‘Collections’ were dropped in the second iteration of the language. This conformance have made a comeback in Swift 4 – along with a series of other string-related updates. For starters, there is a ‘StringProtocol’ for writing extensions through ‘String’ and ‘Substring’. The ‘StringProtocol’, in turn, will follow ‘Bidirectional Collection’ – and both the ‘String’ and ‘Substring’ types will conform to the ‘RangeReplacableCollection’ protocol. For low-level Unicode operations, there is a new Unicode ‘namespace’ (enum Unicode {  ), as a caseless ‘enum’. The interop C string methods have also been tweaked around, with the new version of the language having 2 init (cString) and 2 ‘with cString’ operations. There are changes in the underlying transcoding support of the language as well.

Note: All the string-related new features in Swift 4 are part of the ‘String Manifesto’.

  1. Unicode 9 supported

    Full support for Unicode 9 is yet another high point for the latest Swift version. The language has traditionally run into troubles with the unicode characters – with iOS app developers facing problems, particularly while handling large programs with Unicode. In the latest iteration, there are no bugs or complications with the counting of Unicode characters, and once again, the readability is enhanced with the Unicode 9 support. Devs can now create correct grapheme collections for emojis (‘person + skin tone’, ‘four members of a family, etc.). These countings were, in many cases, erroneous in Swift 3.

Note: The ‘key value observing API’ has undergone an update in Swift 4.

   10. Strings have become collections (reversing an earlier change)

As mentioned earlier, Swift 2.0 had removed Strings as Collections – and Swift 4 has brought it back. While a relatively small workaround, this feature will be mighty helpful for coders – since most strings have either Unicode scalars or sets of characters – both of which can be managed as ‘Collections’. Other instances can be documented with API as ‘special cases’, and worked upon accordingly. With Strings becoming Collections again, a lot more can now be done with the former – right from character-on-character looping, to full reversing. Reiterations can be done directly on a String in Swift 4, and the need for having separate ‘characters’ arrays has been done away with. From ‘Collection’ and ‘Sequence’, more functionalities can be obtained inside ‘Strings’.

Note: There is a new StringProtocol too, for the purpose of declaring functions that had been declared earlier in a String.

   11. More powerful Dictionaries

Unlike in Swift 3, filtering a dictionary in Swift 4 actually returns a new dictionary (instead of an array of tuples). A dictionary in Swift 4 can be initialized with duplicate keys – ensuring that other key-value pairs do not get accidentally overwritten. A tuple (i.e., a sequence of key-value pairing) can be used for dictionary creation as well. Values can be mapped directly in the dictionaries with the new mapValues () method – while custom ‘Dictionary Grouping’ (from sequences) is also supported. In case a dictionary key is missing and a default value has to be assigned, that can be done directly in the latest Swift version – without having to depend on the often-troublesome ‘nil coalescing operator’. What’s more, developers can now filter new objects from both ‘Set’ and ‘Dictionary’. Swift 4 has made Dictionary operations more intuitive than ever before.

Note: Explicitly reserving capacity is another new capability of Dictionary. This operation is available in Sequence too.

E.g., variablename.reservecapacity (10)

   12. Limiting Objective-C inferencing

The @objc compiler attribute is useful. It can be used for handling Swift APIs on the Objective-C platform. That said, there are certain problems with using this Obj-C inference too – particularly in the form of increase in the binary size of the final software, and also the unforeseen creation of ‘selector collisions’ in the platform. In Swift 4, this referencing has become a lot more limited – with explicit inferencing required for only such instances where the entire dynamic dispatch capabilities are required. Classes derived from NSObject no longer need to use the inference, and the code lines that are not being used are not compiled (no redundant compilation). There are certain cases where implicit Obj-C referencing will be still required though (say, in declarations with an @objc attribute).

Note: With the limited Objective-C referencing, the size of a 20 MB app can be brought down to 16-17 MB.

Another new feature in Swift 4 worth a mention is the presence of generic subscripts. The ‘where’ clause can be used for associated type constraints, NSNumber Bridging is available to move away from errors in earlier versions (delivering greater consistency), and a new method – ‘MutableCollection’ – has been provided, for swapping elements from indices. There are several other small yet important additions to Swift 4 – all of them contributing to make the language even more developer-friendly.

Most new features in Swift 4 have backward compatibility (with codes in earlier Swift versions) – and in general, the changes are not as large as those introduced in Swift 3. The Swift Evolution community is constantly evolving (Swift 4.1 was released in October) – and the next version of the language is set to have ABI compatibility and stability, with libraries from different Swift versions being compatible with applications (the feature should be implemented by the end of this year). Swift’s soaring popularity apparently hit a roadblock in mid-2017 – and the new additions in Swift 4 can be instrumental in boosting its adoption among Apple developers worldwide.

Hussain Fakhruddin
Follow me

Hussain Fakhruddin

Hussain Fakhruddin is the founder/CEO of Teknowledge mobile apps company. He heads a large team of app developers, and has overseen the creation of nearly 600 applications. Apart from app development, his interests include reading, traveling and online blogging.
Hussain Fakhruddin
Follow me
 

Leave a Reply

Your email address will not be published. Required fields are marked *