At some point the thought of adding a Widget to my iOS app came to mind which was followed by starting work on adding a widget for my app, My Day Todos. Obviously the first step was to learn how to add a Widget to an iOS app and in that learning process I discovered many things about widgets in iOS first of which was a widget in iOS is a an app extension i.e a Today Extension. While I am still haven’t finished working on the widget for my iOS app, I thought I would take some time out and share what I have learned. In this post, I will share a few important tips and provide an example of how to add a Widget to an iOS app and have the widget UI powered by Html5 via Ionic framework. I added some code to my Github repo, Html5StarterAppWithSwift in order to show how this can be achieved.

There are already too many tutorials out on the Web on how to add a Today extension to an iOS app so I won’t be including that here. Instead I will focus on sharing some of the useful tips which can save a lot of time while building a widget and more importantly my implementation of an Html5 powered iOS widget for a native app.

Html5StarterAppWithSwift

I created this Github repo with the aim to show how to make a native iOS app whose UI is powered by Html5 which in my case was achieved via the Ionic framework. To read more about it, have a look at the repository’s README file. The repo provides an Xcode project template and shows how the Html5 elements can control certain native functionality like Local notifications etc.

How does Html5StarterAppWithSwift, show the widget?

Firstly, to know the process of how to add a widget to an iOS app, I would suggest you go through one of the online tutorials, e.g. this video tutorial proved quite useful to me. 
To add a widget to an iOS app, simply select your project in Xcode followed by selecting Editor -> Add Target in the menu followed by selecting Today Extension as the template for your new target.

The screenshot below shows what an Html5 based widget for an iOS app looks like. It’s the same charting example that is shown in the Charting tab of the main iOS app in Html5StarterAppWithSwift that uses the Chartist library.

The next question would be on how to run the Widget from your Xcode project? for that simply select the Widget Scheme in Xcode and run as shown in the screenshot to the right.

Some very useful tips!!!

While building the widget I ran into a bunch of little issues which while minor caused some frustration mostly because I knew it was simply because it was the first time I was building a widget. I am going to mention some of those below and share my solutions to them.
  1. Sharing resources between your Host app and Today Extension: have a read of the App Extension Programming Guide and you will realise that your App Extension i.e. Widget is independent of your app i.e. Host app. Now what that means is that resources or some code from your Host app is not available to your app extension, at least by default. So in our case the folder www which has all the Html5 contents of our iOS app are not available to our widget when we first add the widget. To make the contents of the www folder available to our widget, we need to make sure they are copied when we build the app via Xcode. So how do we achieve that? go to the project navigator, select the widget target and in build phases add the www folder in Copy Bundle Resources. Have a look the screenshots below to see what I mean,

Minor issues during testing the widget

There were a few minor issues that I faced when trying to test my widget on both a device and an Xcode simulator. Let’s start with the simulator first,

Xcode….”Waiting to attach”

This was a message that I saw entirely too often when testing my widget on the iOS simulator on Xcode. While I couldn’t find a definite solution for it, I did find a few things that helped me minimise the issue. Things such as
  1. Close the notification window when re-running the today extension in the simulator
  2. Stop the widget running in the simulator, run the host(main) app and then run the widget 
This SO answer provides useful tips.

Code signing issues

I ran into some code signing issues while trying to test the widget on my iOS device, while I cannot remember the exact error, I remember the solution to it (I think it was a mismatch of the certificate signing identity used for Widget and the host App?). Anyway the solution is to have the same code signing identity for both your widget and your app in Build Settings i.e. settings shown in the screenshot below.

Sharing NSUserDefaults between Today Extension(widget) and host app

While working on the widget for my app, I came ran into a situation where I wanted to share the data between my widget and my app, I realised that it is not very straight-forward. However thanks to this very useful article (Sharing NSUserDefaults between your app and a Today Extension on iOS), I now know how to share the data between the widget and my app.

Not enough space for the contents of your Today Extension 

One of the problems that I came accross while building a widget for my app was a “lack of enough space” problem. So what happened was I added a new target for a Today Extension followed by adding some content on it and running it on my iOS device only to realise that my widget is not using all available space. What do I mean? well, have a look at the screenshot below to know what I mean

See all the empty space on the left side that is not being used by the widget? That’s the default behaviour but fortunately, the NCWidgetProviding protocol provides a method(widgetMarginInsetsForProposingMarginInsets) that we can use to obtain all the available space in the widget. More like using which we can control all the margins for our widget.
func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets) -> UIEdgeInsets {
let x = 0
let left = CGFloat(x), right = CGFloat(x), bottom = CGFloat(x), top = CGFloat(x)
return UIEdgeInsets.init(top: top, left: left, bottom: bottom, right: right)
}
I am sure you realise that the value of x could be anything.

Conclusion

I hope you find this post helpful and if you like my work, you can support my work by either buying my app My Day Todos or downloading My Day Todos Lite(free), any feedback on my app is most welcome. Additionally I do invest a lot of time on writing my blog as well, so if you have feedback on my posts, that is most welcome.

Leave a Reply

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