Xcode 10.2, macOS Mojave 10.14.4, iOS 12.1 and other betas

    New betas are here and these are some of the most important things that I have learned about them.

    Swift 5 for Xcode 10.2 beta


    Firstly, the latest Xcode beta is bundled with the following Swift version:

    Apple Swift version 5.0 (swiftlang-1001.0.45.7 clang-1001.0.37.7)
    Target: x86_64-apple-darwin18.2.0
    ABI version: 0.6

    Let’s start with the most exciting news:
    Swift apps no longer include dynamically linked libraries for the Swift standard library and Swift SDK overlays in build variants for devices running iOS 12.2, watchOS 5.2, and tvOS 12.2. As a result, Swift apps can be smaller when deployed for testing using TestFlight, or when thinning an app archive for local development distribution.
    Application Binary Interface stability is coming! And this is excellent news. I think this is the one of the most significant issues at the moment with Swift. Not because of side-effects but because of Swift’s failure to deliver on previous promises. Anyway, I even know people who rewrite their Apple Watch extensions to Objective C to reduce the size of binary (something like 15MB vs ~1MB in Objective C). If you want to know more about the state of ABI, follow the links: Swift — ABI Dashboard and Swift ABI Stability Manifesto.

    The @dynamicCallable attribute lets you call named types like you call functions using a simple syntactic sugar. The primary use case is dynamic language interoperability. (SE-0216)


    @dynamicCallable struct ToyCallable {
     func dynamicallyCall(withArguments: [Int]) {}
     func dynamicallyCall(withKeywordArguments: KeyValuePairs<String, Int>) {}
    let x = ToyCallable()
    x(1, 2, 3)
    // Desugars to `x.dynamicallyCall(withArguments: [1, 2, 3])`
    x(label: 1, 2)
    // Desugars to `x.dynamicallyCall(withKeywordArguments: ["label": 1, "": 2])

    This is a huge topic and I have mixed feelings about the feature. So, do read the «What’s new in Swift 5.0» post from Paul Hudson if you want to know more about what is coming.
    Swift 3 mode has been removed. Supported values for the -swift-version flag are 4, 4.2, and 5.
    The time has come. Source compatibility with Swift 3 is no more. It was expected and announced with Swift 5 Roadmap, but still. I highly recommend that you refresh your memory with «Swift 5.0 Release Process» because Swift 5 is almost here. Get ready.
    In Swift 5 mode, switches over enumerations that are declared in Objective-C or that come from system frameworks are required to handle unknown cases — cases that might be added in the future, or that may be defined privately in an Objective-C implementation file. Formally, Objective-C allows storing any value in an enumeration providing it fits in the underlying type.
    These unknown cases can be handled by using the new @unknown default case, which still provides warnings if any known cases are omitted from the switch. They can also be handled using a normal default case.

    If you’ve defined your own enumeration in Objective-C and you don’t need clients to handle unknown cases, you can use the NS_CLOSED_ENUM macro instead of NS_ENUM. The Swift compiler recognises this and doesn’t require switches to have a default case.

    In Swift 4 and 4.2 modes, you can still use @unknown default. If you omit it, and an unknown value is passed into the switch, the program traps at runtime, as does Swift 4.2 in Xcode 10.1. (SE-0192)
    It was, and is, a pain especially if you use no default approach within switches. I remember the ugly workarounds for the new .provisional option of UNAuthorizationOptions property that was introduced in iOS 12. Now, with an unknown case it’s much easier to handle such scenarios.

    Swift Package Manager

    Packages can now customise the minimum deployment target setting for Apple platforms when using the Swift 5 Package.swift tools-version. Building a package emits an error if any of the package dependencies of the package specify a minimum deployment target greater than the package’s own minimum deployment target. (SE-0236)
    The most important news for me concerns Swift Package Manager. Technically, this change can solve a lot of issues that prevent SPM to be useful in the iOS world. In my previous article "Swift Package Manager builds iOS frameworks" I tried to analyse the current state of SPM in the context of iOS development. And now it seems that I’m going to have to reevaluate my thoughts and conclusions.

    There are some bad issues as well:
    Some projects might experience compile time regressions from previous releases;
    Swift command line projects crash on launch with «dyld: Library not loaded» errors.
    Workaround: Add a user-defined build setting 


    A lot of issues have been resolved and as well as other points in the changelogrelated to Swift 5, but they are specific to what you do. Check them, maybe you want to use inherit designated initialisers with variadic parameters, or you were blocked by the deadlock problem due to complex recursive type definitions involving classes and generics, or you are struggling with generic type alias within a @objc method.

    Xcode 10.2 beta

    Apple Clang Compiler

    There are a lot of new warnings for Apple Clang Compiler. And most of them are related to frameworks and modules. It’s quite interesting because it can be associated with Swift Package Manager integration as a dependency tool. The most important ones, in my opinion, are:
    A new diagnostic identifies framework headers that use quote includes instead of framework style includes. The warning is off by default but you can enable it by passing -Wquoted-include-in-framework-header to clang;
    Public headers in a framework might mistakenly #import or #include
    private headers, which causes layering violations and potential module cycles. There’s a new diagnostic that reports such violations. It’s OFF by default in clang and is controlled by the -Wframework-include-private-from-public flag;
    The use of @import in framework headers prevent headers being used without modules. A new diagnostic detects the use of @import in framework headers when you pass the -fmodules flag. The diagnostic is OFF by default in clang and is controlled using the -Watimport-in-framework-header flag;
    Previously, omitting the framework keyword when declaring a module for a framework didn’t affect compilation but it silently did the wrong thing. A new diagnostic, -Wincomplete-framework-module-declaration, and a new fix-it suggests adding the appropriate keyword. This warning is on by default when you pass the -fmodules flag to clang.
    Firstly, how to turn them on: Goto to Build Settings for your application target, find «Apple Clang — Custom Compiler Flags» and put the desired flag to «Other C Flags».

    I tried to build an old, Objective C-based application and found a lot of issues with private headers in public framework headers:

    And some issues with double-quoted imports within frameworks:

    I recommend you run such diagnostics as well and, at least, create issues for your backlog. One day, all these problems will cause you a real headache.

    Build System

    There is also a nice, new Build System feature:
    Implicit Dependencies now supports finding dependencies in Other Linker Flags for linked frameworks and libraries specified with -framework-weak_framework-reexport_framework-lazy_framework-weak-l, -reexport-l-lazy-l, and -l.
    It’s really interesting as well. In general, it means that you can define your implicit dependencies via .xcconfig or even with xcodebuild options and avoid these Link /
    Embed phases within Xcode.


    Debugging has got new features:
    UIStackView properties are now presented in the view debugger object inspector;
    The view debugger presents a more compact 3D layout.

    Xcode can now automatically capture a memory graph, if a memory resource exception is encountered while debugging. To enable memory graph captures go to Diagnostics tab of the scheme’s run settings;
    On iOS and watchOS, Xcode shows the memory limit for running apps in the Memory Report as you approach the limit;

    See the red line? Watchdog sends applicationDidReceiveMemoryWarning(...)
    when you reach the edge. But I thought it would be more useful than it is, to be honest. For now, it just looks like a minor, nice improvement.

    LLDB Debugger

    And LLDB Debugger got some love as well:

    You can now use $0, $1, … shorthands in LLDB expression evaluation inside closures;
    The LLDB debugger has a new command alias, v, for the «frame variable» command to print variables in the current stack frame. Because it bypasses the expression evaluator, v can be a lot faster and should be preferred over p or po.
    I haven’t noticed any performance improvements, but v produces a better output in some cases although it’s not a replacement for po in general, it’s only for the current stack frame with some limitations. See the examples below.


    My favourite section? Playgrounds! Let’s start with known issues:
    Playgrounds might not execute!
    Unfortunately, this is the only news concerning Playgrounds in the current beta.


    Some notes about Simulator:
    Siri doesn’t work in watchOS and iOS simulators;

    Pasteboard synchronisation between macOS and simulated iOS devices is more reliable;
    I really hope it is.
    You’re now only prompted once to authorise microphone access to all simulator devices.
    This is a nice improvement because many people get issues with CI and build agents due to this problem. Now a workaround can be automated or, at least, we can update our guides to set up build agents with «Run a simulator once» step.


    xccov supports merging multiple coverage reports — and their associated archives — together into an aggregate report and archive. When merging reports, the aggregate report may be inaccurate for source files that changed since the time the original reports were generated. If there have been no source changes, the aggregate report and archive will be accurate;
    xccov now supports diffing Xcode coverage reports, which can be used to calculate coverage changes over time. For example, to diff the coverage reports before.xccovreport and after.xccovreport, invoke xccov as follows: xccov diff — json before.xccovreport after.xccovreport;
    Static library and framework targets now appear in the coverage report as top-level entries, with line coverage values that are aggregated across all targets that include the static library or framework. This also resolves an issue where the source files for a static library or framework target would be included in the coverage report even if the target itself was excluded from code coverage in the scheme.
    These changes are excellent news for Continuous Integration. Especially differing. Let your release engineering team know and anyone else responsible for such things.

    However, there are some limitations related to testing parallelisation:
    Recording doesn’t work from Clones when Parallelisation is on;
    Profiling tests don’t behave correctly when test parallelisation is enabled;
    There are also some promising bug fixes:
    If testing fails due to the test runner crashing on launch, Xcode attempts to generate a rich error message describing the failure. This failure is present in the test activity log and appears in stdout if you’re using xcodebuild. The error is also present in the structured logs contained in the result bundle.
    We get a lot of such issues, and usually, it’s not clear at all what is happening. Sometimes, it’s related to incorrect linking, sometimes to system overload. It should help to reduce flakiness.
    Crash reports collected during testing no longer omit important fields such as the termination reason and description.
    No comment just love.

    And the last point about Xcode, useful for companies with a lot of developers, Xcode now supports macOS content caching service. This means that you can have a caching server with Xcode application in your local network.


    I encounterd some problems with the beta. Mostly with third-party tools: Carthage, for example, which doesn’t work, with the following error:

    Could not find any available simulators for iOS

    I checked the available simulator, and it appears that something is broken in the current beta; it’s also impossible to download other runtimes from Xcode, the list of available simulators is just empty (a radar filled):

    $ xcrun simctl list devices --json | grep -A16 12.1
        "com.apple.CoreSimulator.SimRuntime.iOS-12-1" : [
            "availability" : "(unavailable, runtime profile not found)",
            "state" : "Shutdown",
            "isAvailable" : false,
            "name" : "iPhone 5s",
            "udid" : "DDD36346-A76F-42E8-80F4-6F11E1EE4BEB",
            "availabilityError" : "runtime profile not found"
            "availability" : "(unavailable, runtime profile not found)",
            "state" : "Shutdown",
            "isAvailable" : false,
            "name" : "iPhone 6",
            "udid" : "21794717-BC89-45E4-9F57-8CF9D14A87D1",
            "availabilityError" : "runtime profile not found"

    It is a beta, of course. And the changelog is enormous. Be patient and reasonable :)

    P.S. Carthage already has a fix (#2691).

    iOS 12.2 beta

    Okay. It seems like they are polishing their tech-debt and applying security patches. Two things are broken:
    You might be unable to authenticate within Wallet after selecting a card;

    You might be unable to purchase a prepaid data plan using cellular data.
    And Apple News will be available in Canada. Stay tuned.

    macOS Mojave 10.14.4 beta

    The only new thing here is a potential issue with Safari 12.1. After upgrading from Safari 10.1.2:
    After updating to Safari 12.1 from Safari 10.1.2, web pages might not display.
    Workaround: Run the following command in Terminal:

    defaults delete com.apple.Safari
    With the following consequences:
    Warning: You will lose your previous Safari settings after running the command above.

    Final cut

    This article turned out to be much longer than I thought. Well, I did give you all my thoughts on all the sections above. A short version of the whole article is simply, ‘Swift 5 has arrived!’

    Stay tuned and hydrated! And thanks for reading.

    Also popular now: