Skip to main content

Html5 based widget for an iOS app: Today extension powered by the Ionic framework

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.

Comments

Anshul Sharma said…
This is really helpful and informative, as this gave me more insight to create more ideas and solutions for my plan. Excellent and very cool idea and great content of different kinds of the valuable information's.
ios app development company
divya said…
Great post! Thanks for sharing information about html.
web designing course in chennai
Wow what a great blog, i really enjoyed reading this, good luck in your work. Sign IOS App

Popular posts from this blog

Upload to AWS S3 from Java API

In this post, you will see code samples for how to upload a file to AWS S3 bucket from a Java Spring Boot app. The code you will see here is from one of my open-source repositories on Github, called document-sharing. Problem Let’s say you are building a document sharing app where you allow your users to upload the file to a public cloud solution. Now, let’s say you are building the API for your app with Spring Boot and you are using AWS S3 as your public cloud solution. How would you do that? This blog post contains the code that can help you achieve that. Read more below,  Upload to AWS S3 bucket from Java Spring Boot app - My Day To-Do (mydaytodo.com)

Addressing app review rejections for auto-renewing subscription in-app purchase (iOS)

The ability to know what the weather is like while planning your day is a feature of  My Day To-Do  Pro and as of the last update it’s also a part of the  Lite version . Unlike the Pro version it’s an auto-renewing subscription based  in-app purchase (IAP)  in the Lite version. What means is that when a user purchases it, the user only pays for the subscription duration after which the user will be automatically charged for the next period. Adding an  auto-renewing  subscription based IAP proved to be somewhat challenging in terms of the app store review i.e. the app update was rejected by the App Review team thrice because of missing information about the IAP. Therefore in this post I will share my experiences and knowledge of adding auto-renewing IAP in hopes to save someone else the time that I had to spend on this problem. In-App purchase This year I started adding IAPs to My Day To-Do Lite which lead to learning about different types of IAP...

Getting started with iOS programming using Swift (Part 1)

I have not been too fond of Objective-C, which was the primary reason for me to stay away from making iOS apps till now. So what changed? Well Apple has done something very interesting recently and that is the introduction of a new programming language i.e. Swift. Swift is awesome, it almost feels like Python, C++ and Objective-C had a baby with some of their good parts in them. So I have been getting to know Swift and it is an awesome language to program in. What I am going to share with this and a series of blog posts are solutions to some problems that i have encounter while i am trying to finish my first iOS app. The one hurdle that I have encountered while getting started on developing an iOS app is that a majority of the solutions for iOS specific problems provide solutions to them using Objective-C. Which is fair, because Swift has not been around for that long. Anyway let us get started with a few basics, A few basics I would highly recommend having a read of this book...