DynaTimer With DynamicIsland đŸ€©

Furkan
5 min readNov 24, 2022

--

Hi everyone! Today we build little timer app. But it has a Dynamic Island feature đŸ€­

So, let’s get start!

What is Dynamic Island?

Dynamic Island is a feature that resizes the pill-shaped notch. The resizing lets the black area include more information, interactive information that you can tap or long press on to access different functions. (Only Ä°phone 14 Pro and 14 Pro Max)

So let’s create an Xcode Project

I gave project name is “DynamicTimer” don’t forget select the interface SwiftUI

Our UI only have a button it starts our timer!

struct ContentView: View {
@State private var isStartTimer: Bool = false
var body: some View {
VStack {
Text("Start The Time!")
.font(.title)
.foregroundColor(.black)

Button {
isStartTimer.toggle()
} label: {
Image(systemName: isStartTimer ? "pause.fill" : "play.fill")
.foregroundColor(.white)
.frame(width: 150, height: 150)
.foregroundColor(Color.black)
.background(isStartTimer ? .red : .green)
.animation(.easeOut, value: 0.5)
.clipShape(Circle())
}

}
}
}

Yeah, it’s simple play/pause button and it’s state variable

And now we are creating “Timer Attribute” 👇

I’ve created new empty file, now let’s start writing the attribute you can think of it as the model of our dynamic island

Our Timer Attribute

First of all i’ve imported “ActivityKit” the it announced this yer 2022 WWDC Dynamic Island works with ActivityKit.

We’re just going to show an example date, hour and second, for that we add a date to our content state.

So, Dynamic Island model just finished đŸ„ł

Now back to our ContentView

@State private var activity: Activity<TimeActivityAttributes>? = nil
@State private var time: Date? = nil

I’ve imported ActivityKit and wrote this variables:

  • We created our activity variable to start and stop the activity
  • And our time variable to use it with the time variable in the attribute

So let’s start the activity, when button pressed!

  let attribute = TimeActivityAttributes()
let state = TimeActivityAttributes.ContentState(time: .now)

activity = try? Activity<TimeActivityAttributes>.request(attributes: attribute, contentState: state)

Just 3 simple code for start our activity :D

But the activity cannot go on indefinitely, we may have to end it 😅

let state = TimeActivityAttributes.ContentState(time: time)
Task {
await activity?.end(using: state ,dismissalPolicy: .immediate)
}
self.time = nil

3 simple code for end our activity. (You should use concurrency for end the acitivty) don’t forget to set nil time variable

We just finished our ContentView, now we creating a widget target

Click on Xcode File -> New -> Target

Select Widget Extension

Give it a name and don’t forget check “Include Live Activity”

And now, our file created!

Does this code look familiar from somewhere :D In the beginning, we created we don’t need this code for it (But if you don’t want to create it at first, you can use it with the attributes that come with the target.)

We will use the file “
WidgetLiveActivity” you can ignore normal widget file because it’s our home screen widgets.

This is the interface of our Dynamic Island and Live Activity Widget !!!

So let’s gettin deeper

Dynamic Island has 3 property:

  • Compact Leading
  • Compact Trailing
  • Minimal

Check this link from Apple Developer

Let’s continue to complete layout our Dynamic Island!

Now I’m creating a view that shows the date

This is our DateView and it has a “ActivityViewContext” for show the date. After that put this view into the Dynamic Island!

I just putted the view bottom of the island!

Now let’s continue the interface a little more

I just created this views for Live second, current date and current hour.

And putted into dynamic island!!

There is left little thing to before running the project 😁

Don’t forget to check this attribute file target membership to Widget Extension. Because we use widget activity configuration just like that

And don’t forget to add LiveActivities Support to info.plist

Now we can run the project, I’m So Excited đŸ„ł

That’s It Check this for github repo

See you in other articles, bye 🎉

--

--