Posts

Swift Charts with SwiftUI – WWDC22

At WWDC 2022, Apple unveiled Swift Charts, a library to plot graphs and charts. Until now, we were dealing with 3rd party libraries to plot data.

By using SwiftUI’s declarative syntax, we can visualize any kind of data with the chart style we want. Swift Charts has a lot of flexibility and allows a wide variety of presentations.

For this article we’ll follow an iOS project that includes all data visualization types announced by Apple.

What does Swift Charts offer?

Before we get down to coding, let’s examine the Charts library. Here is Apple’s definition:

Swift Charts is a powerful and concise SwiftUI framework for transforming your data into informative visualizations. With Swift Charts, you can build effective and customizable charts with minimal code. This framework provides marks, scales, axes, and legends as building blocks that you can combine to develop a broad range of data-driven charts.

Mark

Apple defines items that visually represent data as Mark. Available Mark types are: Bar, Point, Line, Area, Rule, Rectangle.

Scale

As the name suggests, you can scale variables of your charts using Scales. For example, the x or y axis range of the chart, the colors of the Marks, the range of the plot.

What Are We Going to Build Today?

We’ll create different charts. The finished version of our application will look like this:

Area chart

You can access the source code of the final app here.

Description of The Project Structure

As you can imagine, we need a data for all the charts we will create. To meet this need, we created a struct named ChartData and created random data using separate computed property variables for each Mark type. You can find this struct under the Data folder.

Under the Models folder, you can find the models we created to manage the data, as you can imagine. These are: EnergyConsumption, HeartBeat, Person, Production and Sale.

Under the Modules folder, you will see the Charts we created as separate Views.

Line Chart

We often use the line chart to show data that changes over time and to be able to clearly display the change between them.

We used the line chart to show the number of sales made by a seller by day.

Code:

import SwiftUI
import Charts

// MARK: - View
struct LineChartView: View {
    
    // MARK: Properties
    private let chartData = ChartData.lineChartData
    
    // MARK: Body
    var body: some View {
        VStack {
            GroupBox("Sales Count Per Day") {
                Chart(chartData) { sale in
                    LineMark(
                        x: .value("Weekday", sale.date, unit: .hour),
                        y: .value("Count", sale.count)
                    )
                    .interpolationMethod(.cardinal)
                }
                .padding(.horizontal, 16)
            }
            .backgroundStyle(Color.white)
        }
        .navigationTitle("Line Chart")
    }
}

// MARK: - Preview
struct LineChartView_Previews: PreviewProvider {
    static var previews: some View {
        LineChartView()
    }
}

Output:

Line chart

Area Chart

Area Chart basically represents the combined version of line chart and bar chart. Usually, we use it to show the cumulative sum of one or more numeric values based on a second variable.

In our project, we used the area chart to show the annual energy consumption increase.

Code:

import SwiftUI
import Charts

// MARK: - View
struct AreaChartView: View {
    // MARK: Properties
    private let chartData = ChartData.areaChartData
    
    // MARK: Body
    var body: some View {
        VStack {
            GroupBox("Yearly Energy Consumption") {
                Chart(chartData) { consumption in
                    AreaMark(
                        x: .value("", consumption.date, unit: .month),
                        yStart: .value("", consumption.monthlyMinMegawatt),
                        yEnd: .value("", consumption.monthlyMaxMegawatt)
                    )
                }
                .padding(.horizontal)
            }
            .backgroundStyle(Color.white)
        }
        .navigationTitle("Area Chart")
    }
}

// MARK: - Preview
struct AreaChartView_Previews: PreviewProvider {
    static var previews: some View {
        AreaChartView()
    }
}

Output:

Area chart

Bar Chart

Bar Chart is preferred for visualizing numeric values as bars divided into categories.

In our project, we visualized the bus production by month with the help of Bar Chart.

Code:

import SwiftUI
import Charts

// MARK: - View
struct BarChartView: View {
    // MARK: Properties
    private let chartData = ChartData.barChartData
    
    // MARK: Body
    var body: some View {
        VStack {
            GroupBox("Number of Bus Production by Month") {
                Chart(chartData) { production in
                    BarMark(
                        x: .value("Bus Production", production.count),
                        y: .value("Month", production.date, unit: .month)
                    )
                    .foregroundStyle(by: .value("Bus Production", production.count))
                }
                .padding(.horizontal, 16)
            }
            .backgroundStyle(Color.white)
        }
        .navigationTitle("Bar Chart")
    }
}

// MARK: - Preview
struct BarChartView_Previews: PreviewProvider {
    static var previews: some View {
        BarChartView()
    }
}

Output:

Bar chart

Point Chart

Another chart type we use to visualize time-varying values and data groups is Point Chart.

We used the Point Chart to visualize heart rate data, as Apple prefers in the Health app.

Code:

import SwiftUI
import Charts

// MARK: - View
struct PointChartView: View {
    
    // MARK: Properties
    private let chartData = ChartData.pointChartData
    
    // MARK: Body
    var body: some View {
        VStack {
            GroupBox("Heart Beats by Time") {
                Chart(chartData) { person in
                    PointMark(
                        x: .value("Time", person.heartBeat.time, unit: .minute),
                        y: .value("Heart Beat", person.heartBeat.beat)
                    )
                    .foregroundStyle(by: .value("Heart Beat", person.heartBeat.beat))
                }
                .padding(.horizontal, 16)
            }
            .backgroundStyle(Color.white)
        }
        .navigationTitle("Point Chart")
    }
}

// MARK: - Preview
struct PointChartView_Previews: PreviewProvider {
    static var previews: some View {
        PointChartView()
    }
}

Output:

Point chart

Bonus: Mixed Chart

As a bonus, we combined line chart and point chart data in one chart. Swift Charts gives us this convenience in every chart. You can also experiment with different types of graphic creation combinations yourself.

Code:

import SwiftUI
import Charts

// MARK: - View
struct MixedChartView: View {
    
    // MARK: Properties
    private let lineChartData = ChartData.lineChartData
    private let pointChartData = ChartData.pointChartData
    
    // MARK: Body
    var body: some View {
        VStack {
            GroupBox("Mixed: Sales Count & Heart Beat") {
                Chart {
                    ForEach(lineChartData) { sale in
                        LineMark(
                            x: .value("Weekday", sale.date, unit: .minute),
                            y: .value("Count", sale.count)
                        )
                        .interpolationMethod(.cardinal)
                    }
                    .foregroundStyle(.green)
                    
                    ForEach(pointChartData) { person in
                        PointMark(
                            x: .value("Time", person.heartBeat.time, unit: .minute),
                            y: .value("Heart Beat", person.heartBeat.beat)
                        )
                        .foregroundStyle(by: .value("Heart Beat", person.heartBeat.beat))
                    }
                    
                }
                .padding(.horizontal, 16)
            }
            .backgroundStyle(Color.white)
        }
        .navigationTitle("Mixed Chart")
    }
}

// MARK: - Preview
struct MixedChartView_Previews: PreviewProvider {
    static var previews: some View {
        MixedChartView()
    }
}

Output:

Mixed chart

Properties

Now I’m going to show you briefly some of the Properties. You can make changes to your charts by using these properties.

X & Y Position

Actually, we have already used X and Y posts in our Marks. They exist to define our dataset to be located on the X and Y axes.

Foreground Style

We use Foreground Style for options such as coloring and grouping our data. You can see these two options in different Charts within the project. The MixedChart we created would be a good example of this.

Symbol

As the name suggests, we can use Symbol to mark the intersecting points on the X and Y axes in our graphics with different symbols. Thus, you get a graphic that is easy to distinguish.

The chart below is an example of how we can diversify our chart with the Squareand Circle symbols. Moreover, the Charts library does this for us automatically.

Line chart

Line Style

It is used to create new and custom plots for the Marks used in our chart. For example, to create bolder and rounded lines.

Conclusion

As you can see, using a few different modifiers, we can quickly create many different kinds of graphics without much effort.

Of course, these are not the only things we can do with Swift Charts. Apple has released many video series for us. You can learn how to create Charts in different structures by watching these videos.

Where to Go From Here?

Apple Docs — Swift Charts

Hello Swift Charts — WWDC22

Design an Effective Chart — WWDC22

Design App Experiences With Charts — WWDC22

Swift Charts: Raise The Bar — WWDC22

What’s New in Swift 5.7, WWDC 22

Great new features await us with Swift 5.7. Some are enhancements to Swift, while others are enhancements and improvements to make it easier for us to write code.

In this article, we will examine the innovations that come with Swift 5.7 with examples.

Clock, Instant and Duration

Swift announces the innovations it offers to make time and duration management more stable in the SE-0329 section.

Clock

Clocks represent a way of measuring time passing. There are two built in: the continuous clock keeps incrementing time even when the system is asleep, and the suspending clock does not.

SuspendedClock

  • Measuring device time
  • Delays for animations

ContinuesClock

  • Measuring human time
  • Delays by an absolute duration
// Measure elapsed duration of work

let clock = SuspendingClock()
let elapsed = await clock.measure {
  await someLongRunningWork()
}

// Measure elapsed duration of work

let clock = ContinuousClock()
let elapsed = await clock.measure {
  await someLongRunningWork()
}

Instant

Instants represent an exact moment in time. Instants are there to be used to compare moments.

Duration

Duration can be used to represent the time elapsed between two Instant.

New “if-let” Unwrapping Syntax

With Swift 5.7, you will now be able to unwrap an optional value in a shorter way. This was announced in section SE-0345.

// Swift 5.6 and prior

let appCircle: AppCircle?

if let unwrappedAppCircle = appCircle {
    // `appCircle` is of type `AppCircle`
}

// Swift 5.7

let appCircle: AppCircle?

if let appCircle {
    // `appCircle` is of type `AppCircle`
}

Multi-statement closure parameter/result type inference

We no longer have to define result types when we use the closures we love to use. Swift will handle this for us. See SE-0326.

As you know before, we had to define these result types and the code we wrote was increasing.

let points = [25, 47, 12, 78, 90]

let results = points.map { point in
    if point >= 70 {
        return "\(point): Well done!"
    }
    
    return "\(point): Nice try! :("
}

/* Old way
let points = [25, 47, 12, 78, 90]

let result = points.map { point -> String in
    if point >= 70 {
        return "\(point): Well done!"
    }
    
    return "\(point): Nice try! :("
}

*/

Opaque Parameter Declarations

If you’ve ever been interested in SwiftUI, you’ve probably heard of the ‘some’ keyword. When we put this keyword in front of a parameter, the parameter becomes Opaque.

Well, if you say what will be the use of these Opaque type parameters, our code will be more readable and reduced when using Swift Generics with Opaque types. Additionally, we can use the ‘any’ keyword.

See SE-0341 and SE-0309
Some

  • Holds a fixed concrete type
  • Guarantees type relationship

Any

  • Holds an arbitrary concrete type
  • Erases type relationships
// `some`
protocol Animal {
  associatedtype Feed: AnimalFeed
  func eat(_ food: Feed)
}

struct Farm {
  func feed(_ animal: some Animal) {
    let crop = type(of: animal).Feed.grow()
  }
}

// `any`
let technologies: [any Equatable] = ["AppCircle", 10]

Regex

Regex operations are now easier with Swift 5.7. Prior to this we had to deal with Range and NSRegularExpression.

Now, thanks to Regex type, we will be able to do the regular expression operations we need more easily.

See SE-0350.

Regexes can be created at run time from a string containing familiar regex syntax. If no output type signature is specified, the regex has type Regex<AnyRegexOutput>, in which captures are existentials and the number of captures is queryable at run time. Alternatively, providing an output type signature produces strongly-typed outputs, where captures are concrete types embedded in a tuple, providing safety and enabling source tools such as code completion.

let pattern = #"(\w+)\s\s+(\S+)\s\s+((?:(?!\s\s).)*)\s\s+(.*)"#
let regex = try! Regex(pattern)
// regex: Regex<AnyRegexOutput>

let regex: Regex<(Substring, Substring, Substring, Substring, Substring)> =
  try! Regex(pattern)

By examining the code block below, you can better understand how we use the new regex type with a comparative example.

let text = "AppCircle is a great tool for CI/CD pipeline management."

// Old
print(text.ranges(of: "for"))
print(text.replacing("great", with: "excellent"))

// New
print(text.ranges(of: /[a-z]for/))
print(text.replacing(/[a-z]at/, with: "excellent"))

What is New in SwiftUI 4.0, WWDC 2022

WWDC 22 is passed so quick, isn’t it? SwiftUI is one of the most awaited subjects from developers in WWDC 22. Some of the developers are satisfied with the new features for SwiftUI, but some are not.

Here are the features that will be in SwiftUI 4.0, iOS 16.

Hide Home Button(Indicator)

Apple’s Documentation

Some screens are required a lot of taps and focus from the user. To achieve this goal, we can hide the bottom native indicator in SwiftUI not.

var body: some View {
    EmptyView()
        .persistentSystemOverlays(.hidden)
}

Hide Home Button(Indicator)

Navigation Stack

Apple’s Documentation

The new way to manage navigations instead of NavigationView.

With the new NavigationStack, we can define multiple destinations by the model.

let vehicles: [Vehicle] = [
    .init(name: "Car", iconName: "car"),
    .init(name: "Bus", iconName: "bus"),
    .init(name: "Airplane", iconName: "airplane")
]

var body: some View {
    NavigationStack {
        List(vehicles) { vehicle in
            NavigationLink(value: vehicle) {
                Label(vehicle.name, systemImage: vehicle.iconName)
            }
        }
        .navigationDestination(for: Vehicle.self) { vehicle in
            VehicleDetailView(vehicle: vehicle)
        }
    }
}

Navigation Stack

Half Sheet

It is one of the features developers mostly demand. Finally, Apple is making it public for us!

All we need to do is call the presentationDetents function of the view we will show as the half sheet.

The function takes detents as the parameter to set the height of the sheet. We can also set a constant height by typing .height(200).

@State var isPresentedHalfSheet: Bool = false

var body: some View {
    Button {
        self.isPresentedHalfSheet.toggle()
    } label: {
        Text("Present half sheet")
    }
    .sheet(isPresented: $isPresentedHalfSheet) {
        HalfSheetView()
            .presentationDetents([.medium, .large])
    }
}

Half Sheet

Swift Charts

Apple’s Documentation

There are different chart styles we can use in the library.

BarMark, LineMark, AreaMark, PointMark, RectangleMark, RuleMark.

Swift Charts

Here is an example of the bar chart.

let chartData: [KeyValue] = [
    .init(key: "A", value: 5),
    .init(key: "B", value: 10),
    .init(key: "C", value: 15)
]

var body: some View {
    Chart(chartData) {
        BarMark(x: .value("Key", $0.key),
                y: .value("Value", $0.value))
    }
}

Swift Charts

Multi Date Picker

Apple’s Documentation

The component provides to choose multi dates through the native date picker.

@State var selectedDates: Set<DateComponents> = []

var body: some View {
    MultiDatePicker("Dates", selection: $selectedDates)
}

Multi Date Picker

Custom Layout

Apple’s Documentation

In case the layout style has to be changed by the user’s interaction, AnyLayoutprovides to achieve it.

@State var changeLayout: Bool = false

var body: some View {
    let layout = changeLayout ? AnyLayout(HStack()) : AnyLayout(VStack())

    VStack {
        layout {
            Text("First")
            Text("Second")
        }

        Button {
            self.changeLayout.toggle()
        } label: {
            Text("Change Layout")
        }
    }
}

Custom Layout

Photos Picker

Apple’s Documentation

It is used to choose multiple photos in the album.

@State var selectedPhotos: [PhotosPickerItem] = []

var body: some View {
    PhotosPicker(selection: $selectedPhotos) {
        Text("Choose photos")
    }
}

Photos Picker

Shape Style Extensions

We can set foreground and background styles to views. These styles support set gradient colors and shadows.

var body: some View {
    VStack {
        VStack {
            Image(systemName: "person")
        }
        .background(in: Circle().inset(by: -20))
        .backgroundStyle(.orange.gradient)
        .foregroundStyle(.white.shadow(.drop(radius: 1)))

        VStack {
            Image(systemName: "house")
        }
        .background(in: RoundedRectangle(cornerRadius: 16).inset(by: -20))
        .backgroundStyle(.orange.gradient)
        .foregroundStyle(.white.shadow(.inner(radius: 1)))
    }
}

Shape Style Extensions

ViewThatFits

Apple’s Documentation

It decides which view will be fit to the screen and it will be the one only visible.

The longer text won’t fit in the portrait mode, therefore the shorter one will be visible. Since the longer one will be able to fit in the landscape mode, it will be visible.

var body: some View {
    ViewThatFits {
        Text("Hello, I am the longer text and most probably I will be visible only in the landscape mode")
            .frame(width: 700, height: 300)
        Text("Hello, I am the shorter text")
            .frame(width: 300, height: 100)
    }
}

ViewThatFits

Mixed-State Toggle

Apple’s Documentation

Sometimes we need a parent toggle states that are associated with its sub toggles. DisclosureGroup provides a structure for that.

@State var profileNotificationsIsOn: Bool = false
@State var campaignNotificationsIsOn: Bool = false
@State var emailNotificationsIsOn: Bool = false

var body: some View {
    DisclosureGroup {
        Toggle("Profile Notifications", isOn: $profileNotificationsIsOn)
        Toggle("Campaign Notifications", isOn: $campaignNotificationsIsOn)
        Toggle("E-Mail Notifications", isOn: $emailNotificationsIsOn)
    } label: {
        Toggle("Notifications", isOn: [
            $profileNotificationsIsOn,
            $campaignNotificationsIsOn,
            $emailNotificationsIsOn
        ])
    }
 }

Mixed-State Toggle

Multiline TextField

Apple’s Documentation

In SwiftUI 4, we are able to define specific ranges of a textfield’s line count. Something like, from 1 to 2, from 5 to endless.

@State var textFieldText: String = ""

var body: some View {
    TextField("I am just a text field", text: $textFieldText, axis: .vertical)
        .lineLimit(...2)
}

Multiline TextField

We’ve tried to list some of the major improvements announced for SwiftUI at WWDC 2022 this year. Of course that’s not all! We’re still digging through the documentation and will add more as we find new additions.

Stick around our blog to find more WWDC 2022 articles.

Modern Layout on UIKit with UICollectionView Compositional Layout

Creating collection views for iOS apps were pretty straightforward. A simple UICollectionFlowLayout would create flowing lists or grids of items. But things got a lot harder when the layout got a little more complex. A horizontal list within a vertical collection view required some extra tricks that every experienced iOS developer has inevitably used. Hopefully, at WWDC19, Apple introduced UICollectionView Compositional Layout, along with Diffable Data Sources. Now we can create nested layouts via and creating these layouts are quite easy.
We are going to look at these two new APIs today. First, we are going to create UICollectionView Compositional Layout object and then we’ll to feed the UICollectionView using UICollectionViewDiffableDataSource.

UICollectionView Compositional Layout

When we are creating new UICollectionViewCompositionalLayout we need three things; Section, Group and Item. Section is same as before but here we have actually new two things here, Group and Item. Think Group as another UICollectionView that has multiple UICollectionViewCell. Lastly, Item is a UICollectionViewCell. Sections has Groups and Groups has Items. See below figure for basic understanding.
Basic demonstration of Section, Group and Item inside UICollectionView Compositional Layout

Section and group

Let’s create our first and fresh layout. 
[gist id=”f10b1b48fa8d2ff69f7539b13ec29cb3″ /]
Above code snippet will produce below layout. Also at Line: 74, you will see orthogonalScrollingBehavior property is equal to .groupPaging. This property setup will make our layout scrollable by groups. 
Outer and inner group
Also we have other useful options for orthogonalScrollingBehavior. Let’s take a quick look of them.
Continuous
It removes pageable scroll behaviour and makes our group scrollable continuously.
ContinuousGroupLeadingBoundary
It behaves like both .groupPaging and .continues options. You can scroll the group continuously but when you stop scrolling your group will fit the screen like .groupPaging smoothly. 
None
The section does not allow users to scroll its content orthogonally. In our case, all the groups that we created will be layout vertically inside its own section. 
This is all about creating UICollectionViewCompositionalLayout. Simple is that! 
So what’s next? Without data a layout is nothing for us. For the next step we will create and implement our UICollectionViewDiffableDataSource. But first let’s look at what it is:

UICollectionViewDiffableDataSource

The classic and old way was using UICollectionViewDataSource. We were inheriting the protocol to our UIViewController and there were bunch of delegate methods for what cell to display, how many cells to display, which section to display the cells in, and so on.
The modern and new way is UICollectionViewDiffableDataSource and it removes most of the logical work and gives us convenience. It allows us to write simpler, clearer and error free code.
With this new approach we are just going to tell our modern data source to what Section and Item to display rather than the how many items to display.
The new diffable part is coming from that whenever you want to update your UICollectionView with new data source, the modern data source will calculate the differences between your old and new data and only will update different parts. This will reduce the amount of code you wrote and make your UICollectionView work high performance.
As I mentioned above we need to create Section and Item. Let’s create them and let me explain the details.
[gist id=”9d47e7aeafbe5ddec462d5bf63c23066″ /]
Why our Section and Item is implementing Hashable protocol? To determine the changes between old and new data. Hashable protocol makes this possible. Functions that we created in Section class are needed for hashing and checking if two Section are equal to each other. 
Now it’s time to create actual UICollectionViewDataSource’s itself. See code snippets below.

Generating new UICollectionViewDataSource

[gist id=”ab34372ecbd11fc25ee5187d0a981afe” /]

We defined two typealias for making our code more readable and clean. You can ask What is Snapshot anyway? NSDiffableDataSourceSnapshot is basically stores your Sections and Items. You can think of it as reference for your modern data source.
Also we must create a SupplementryView for our sections. It’s simple as above code snippets shows. 
Are we done yet? Nope. We need one last thing to implement. We must apply our Snapshot to our modern data source. How we are going to make it happen? See below code snippet.
[gist id=”2feb2068bfea865a6c7d1e1219e3075d” /]
We defined our sections as a class variable and using it applied our snapshot to data source. Every time you update your sections just call applySnapshot method and voila! you successfully updated your modern data source.

Summary

In this article you learned how to implement UICollectionViewCompositionalLayout and UICollectionViewDiffableDataSource to your new project as modern ways. You can challenge yourself with different types of layouts.

Where to Go From Here

You can check Apple’s official documentation: https://developer.apple.com/documentation/uikit/uicollectionviewcompositionallayout

Also you can watch WWDC19 video about Collection View Layouts: https://developer.apple.com/videos/play/wwdc2019/215/

Apple also has a Diffable Data Source video: https://developer.apple.com/videos/play/wwdc2019/220

12 Essential Desktop Apps for iOS Developers Header

12 Essential Desktop Apps for iOS Developers

For developers, using only the Code Editor or IDE to develop applications isn’t enough. While IDEs have many features to improve developer workflow, different apps focused on a single task does the job better. Here are 12 essential desktop apps we use and recommend for iOS developers:

Version Control

Tower ($69-99/year) macOS/Windows

Website

For those who prefer GUIs over CLI’s, Tower is a Git client that has all the functions Git has, and does it in a very simplified way. Adding remotes, managing branches and harder stuff like rebasing can be done via buttons and dragging/dropping. It can setup git-flow branching system, and has Gerrit support. You can choose which diffing tool you want to use to resolve conflicts. macOS version is going a little ahead of the Windows version, but both are very good.

File Diffing & Merging

Kaleidoscope ($69.99) macOS

Website

There is always the free FileMerge bundled with macOS, but it’s UI is old and non-ascii files and non-text formats are not supported. Kaleidoscope has a nice UI, and it can compare images, files and folders. It has built in support for Git, SVN and Mercurial as well. There’s also an iPad version, which is sold for $19.99.

Documentation

Dash ($29.99) macOS

Website

Developers spend a good chunk of their time reading documentation. Dash collects documentation from hundreds of programming languages and frameworks. You can navigate among them and it has good fuzzy search. It also integrates with most of the IDEs and automation software.

Dash for macOS

A Companion for SwiftUI ($49.99) macOS

Website

Apple’s SwiftUI documentation is lacking depth and some modifiers don’t have an overview. A Companion is SwiftUI is an app that lists all SwiftUI Types, Protocols and Methods with clear examples and explanation on how they work. You can also preview some of the types if they are also available on the Mac.

For a list of new things added to SwiftUI with iOS 15, check out our Major iOS 15 API Changes for Developers article.

A Companion for SwiftUI

View Debugging

Reveal ($59-119) macOS

Website

Reveal is a view debugging tool for UIKit apps. It’s much like the Web Inspector in browsers. You can see the entire view hierarchy in 2D or 3D, and filter views based on their memory address. You can inspect every view and its underlying CALayer, and updating a value from the inspector updates the app being debugged. It also inspects Auto Layout constraints and they can be altered as well. Reveal saved us many hours debugging UIs.

Reveal for macOS

Regular Expressions

Patterns ($2.99) macOS

Website

Patterns is an app to test and write Regular Expressions. It also exports code in a selected programming language

Patterns for Mac

Push Notification

Knuff  (Free, Open Source)

GitHub

Knuff is an app to test push notifications. You can provide a JSON payload and select a certificate. Then given a device token, you can send notifications instantly. It also has an iOS app.

Knuff for macOS

HTTP Client

Paw ($49.99) macOS

Website

If you’re making an app that communicates with a server API, then Paw is highly recommended. You can add all the requests and Paw will send them and display responses. It exports code to a variety of networking libraries. You can also create variables from response values. It supports multiple server environments. You can import Postman files too.

Paw Client for Mac

Visuals

Codye (Free, with Pro version $8.99) macOS

Website

With Codye, you can generate screenshots for code snippets in an elegant way.

Codye UI Mac

PaintCode ($199/year) macOS

Website

If you want to draw all visuals, iconography with code, PaintCode is a must. You can import vector graphics or draw your own and PaintCode gives you the UIBezierPath / CoreGraphics code. You can also parameterize certain values and they become configurable in your app.

PaintCode 3

ColorSnapper 2 ($14.99) macOS

Website

ColorSnapper is a color picker that can convert colors to values in code. You can easily get Swift/Obj-C UIColor/NSColor values from a color you picked. It also supports advanced settings to match copied value to match your code style.

ColorSnapper 2 Mac

Disk

DevCleaner for Xcode (Free)

Website

While developing in Xcode, the Developer folders increase in size over time. DevCleaner is a free tool that cleans your Xcode artifacts, such as DerivedData, iOS Images, Simulators, and more… You can pick what to delete and it supports multiple Xcode installations.

DevCleaner for Xcode

We’ve tried to list all the desktop apps we use frequently while developing iOS apps. If you’ve found this article useful, feel free to share this with others.

 

Major iOS15 API Changes for Developers

Major iOS 15 API Changes for Developers

Every year after WWDC, developers who make apps for iOS start working on all the changes and add new features. With next release coming in Autumn/Fall of 2021, we’ve put up a comprehensive list of developer-facing iOS 15 API changes for developers.

Brand New APIs

Apple introduced a few brand new user-centric features for iOS 15, which was also the highlight of the WWDC21 keynote.

SharePlay

With SharePlay, your app’s features can be shared through FaceTime calls. If you have a media streaming app, you can use SharePlay APIs to let users watch or listen to media simultaneously. If your app is using AVFoundation to display content, then most of the work will be handled automatically. All you have to do is to use the new Group Activities API (https://developer.apple.com/documentation/GroupActivities) to provide that your app supports SharePlay and details about your content.

shareplay image

Note: Apple recently released a statement that SharePlay feature won’t be available on the initial release of iOS 15. It’ll be added via an update later this fall. More information here: https://developer.apple.com/news/?id=mxaeu6er

Focus Mode

Prior to iOS 15, users had the option to turn on Do Not Disturb mode to eliminate distraction from notifications and calls. iOS 15 adds the option to create different Focus Modes. Every mode can have their own list of allowed apps and contact list. Modes can be activated via a location change (arriving at the office), a time schedule, or when an app launches (when I launch Mail or Xcode).

In support of focus modes, Apple also introduced notification importance levels. With it, the system can determine whether to display a very important notification, breaking the rules of Focus mode, or not display a trivial notification until focus mode ends. Your app needs to categorize the notification types.

To see the types and how to configure, check the Notifications segment in Human Interface Guidelines: https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/notifications

App Store Changes

App Store is getting new capabilities that will help you marketing your app. You can now create versions of your product detail pages and target them to different segments of potential users. If you have special events for a time period, App Store can display these events on the home page.

App Store

StoreKit API got a major new version as well. With StoreKit 2, Apple has simplified the use of StoreKit, implementing modern Swift features.

There is a new App Store Server REST API as well. Developers can query subscription statuses, get in-app purchase history of a user, and can send usage data to Apple in case the user asks for a refund.

Later this year, apps can extend the subscription’s deadline up to 90 days due to an error in their content delivery. Ability to look up a user’s refund history and retrieve invoices from an order id is also coming later this year. More information on the server API here: https://developer.apple.com/documentation/appstoreserverapi

Apple’s beta distribution platform, Testflight can distribute Mac apps now. It only works for macOS 12 (Monterey) apps though.

ScreenTime API

With the ScreenTime API, apps can apply parental controls based on the app’s usage via the ScreenTime API.

More on ScreenTime API here: https://developer.apple.com/videos/play/wwdc2021/10123/

ShazamKit

Now developers can use Shazam’s audio recognition capabilities in their own apps.

More on ShazamKit here: https://developer.apple.com/shazamkit/

Nearby Interaction API

If you’re making an accessory that communicates with an Apple Device that has a U1 chip, you can use the Nearby Interaction API to make UWB (Ultra Wideband) communication between the device and your app. Apple uses this API to help users locate AirTags.

More on Nearby Interaction API here: https://developer.apple.com/nearby-interaction/

Object Capture

Added with RealityKit 2, Object Capture turns your Apple device into a 3D scanner. By taking multiple images of a real-world object, the object is turned into a detailed 3D model you can use and distribute.

More on Object Capture here: https://developer.apple.com/augmented-reality/object-capture/

Swift

Swift Programming Language is getting lots of new features this year. Main focus during WWDC21 was on Concurrency. With it, Swift gets the async/await syntax to handle asynchronous code. All async functions inside iOS SDK is also updated for this new syntax.

Concurrency in Swift Example COde

Unfortunately, Apple acknowledged that concurrency features will not be backwards compatible, meaning it will only run on iOS 15 and above. But there is always hope: https://github.com/apple/swift/pull/39051

Conversion between CGFloat and Double

Starting with Swift 5.5, the compiler can convert Double values to CGFloat and vice versa, which previously required explicit type declaration.
https://github.com/apple/swift-evolution/blob/main/proposals/0307-allow-interchangeable-use-of-double-cgfloat-types.md

Other Swift 5.5 Additions

There are other Swift improvements like local lazy variables, Swift package collections, and Codable support to enum cases with associated values, and more.

Check the WWDC session video for a deeper dive at what’s added: https://developer.apple.com/videos/play/wwdc2021/10192/

SwiftUI

Apple’s new declarative UI framework, SwiftUI is getting developers excited for new additions every WWDC. Here are some of the SwiftUI changes in iOS 15:

AsyncImage

SwiftUI now has a view type that can load images asynchronously.

https://developer.apple.com/documentation/swiftui/asyncimage/

Refreshable

Any View can have pull-to-refresh functionality, and List views get UI handling automatically.
https://developer.apple.com/documentation/swiftui/label/refreshable(action:)

Animation modifier change

.animation() modifier caused glitches when a value that’s not associated with the animation was updated, or any time a system-wide animation is triggered (like rotating the phone to landscape). New .animation(_ value:) modifier changes that. It triggers the animation when only passed binding value updates.

Search bars

search bars

Any view inside a NavigationView can use .searchable() modifier, which adds a search bar to the top of the view and calls a closure whenever the search query changes. Listening to changes can be disabled and search closure gets called when user taps a button. You can even add search suggestions.
More on search here: https://developer.apple.com/videos/play/wwdc2021/10176/

Changes to Alert and ActionSheet syntax

Previously, alert modifiers required to explicitly create actions inside an alert, the alert itself and finally return the alert. New syntax lets developers define buttons with roles and that’s it.

action sheet in swift ui

Buttons with roles

SwiftUI’s Button type initializer now can take a ButtonRole object. The predefined values for ButtonRole is the same as the ActionSheet actions: destructive, cancel and default(pass nil to make a button default)
https://developer.apple.com/documentation/swiftui/buttonrole/

Updates to List (list element bindings, individual separator insets, custom swipe actions)

We knew that SwiftUI’s List view was using UITableView in the background, but it missed UITableView’s customization and flexibility. With the next release, SwiftUI adds bindings to list elements individually, separator insets can be configured on cell level and custom swipe actions can now be added.
https://developer.apple.com/documentation/swiftui/list/

.task()

Previously, we used .onAppear() modifier to load async content after a view got displayed. Now there is a more safe .task() modifier to run async tasks after a view is rendered initially.

For more in depth information and other improvements, check out WWDC’s What’s New in SwiftUI session: https://developer.apple.com/videos/play/wwdc2021/10018/

We also suggest all SwiftUI developers to watch “Demystify SwiftUI” talk as well: https://developer.apple.com/videos/play/wwdc2021/10022/

Xcode

Xcode 13 also got many improvements this year.

Custom documentation with DocC

Xcode now takes markdown comments and inline documentation and displays them with Apple’s own documentation style. DDoC format can also be used outside Xcode, but it’s not widely supported yet.

Better version control

Apple added support for Code Reviews and Pull Requests. Version control tab also got many small improvements.

Vim Mode

For those who are used to Vim’s commands, Xcode now has a Vim Mode that maps all vim keyboard commands to Xcode. To enable select Editor -> Vim Mode.

Better code completion

Xcode now auto fills when you are unwrapping an optional with if-let, and switch cases gets auto-filled as well.

Foundation and UIKit

New Swift AttributedString Type

Swift now has its own AttributedString type. Create an AttributeContainer value to style chunks of text.

It also has built-in markdown support. All SwiftUI Text types are also accepting AttributedString values.
https://developer.apple.com/documentation/foundation/attributedstring

Date() -> Date.now

Date class now has a direct property to get the current date and time. A nice to have addition.
https://developer.apple.com/documentation/foundation/date/3766590-now/

Changes to UIWindow key window behavior

If your app is using multiple windows and calling making them key window, the behavior is changing in iOS 15:

Improvements to UICollectionView and UITableView Cell Prefetching and Reloads

UIKit team also made improvements to the way cells are prefetched in a UITableView and UICollectionView. This brings a large performance benefit.

They also added the reconfigure method, which lets you directly update a certain cell, instead of reloading the entire table view. More info on both is here:
https://developer.apple.com/videos/play/wwdc2021/10252/

UIButton Configuration

New UIButton Styling

UIButton class got more customizable thanks to the UIButton.Configuration object. Title, subtitle, image setup, paddings between items, background/foreground color and many more options are available. You can define these styles or override the predefined styles to fit your app’s design system.
https://developer.apple.com/documentation/uikit/uibutton/configuration

Bottom Sheets

UIKit has support for bottom drawer sheets in iOS 15. UISheetPresentationController class lets you present smaller-than fullscreen sheets inside your app. Sheets can determine their height by using detents. Detents are height breakpoints that the sheet can grow/shrink to.

More information here:
https://developer.apple.com/videos/play/wwdc2021/10063/

SF Symbols

Apple’s Design team makes new additions every year to help designers and developers to make better functioning apps. SF Symbols was a step in this direction. This year, SF Symbols got a lot more new symbols and more features.

Symbol Variants

Apple grouped symbols into variants. A symbol can have a regular, slashed, enclosed and other versions within the same group.

Variants in SF Symbols 3

There are also variants for icons for different languages and writing styles.

Localized variants for sf symbols

Symbol Colors

Now designers can pick between different styles of the symbols. Previously we had monochrome and multicolor variants. Now there are 2 new styles: Hierarchical and Palette. You can pick a single base color for hierarchical style or two colors for palette to modify icons based on your app’s color palette.

Symbol Colors

Custom Symbols

Now designers can also add their own custom symbols to sf symbols. Developers than can import them to their project and all the benefits of the SF Symbols arrive with them.

For all the new additions to SF Symbols check the WWDC talk: https://developer.apple.com/videos/play/wwdc2021/10097/

SF Arabic

San Francisco is Apple’s official font for all their products. This year, they added an Arabic version of the San Francisco font, called SF Arabic. You can download SF Arabic and all other Apple fonts here: https://developer.apple.com/fonts/

There are many other additions, changes and improvements on iOS 15, and listing all of them here would be impossible. We’ve tried to list major developer-facing iOS 15 API changes for developers.

To try out and use all the new additions, you need to use Xcode 13. As Appcircle, we support building with Xcode 13. And every new beta is available within 24 hours after its release. You can start using Appcircle for free.