Since iOS 8, Apple has made various aspects of the iOS available for 3rd-party developers to plug into. Those include plugging your own custom keyboard for your apps, or creating a widget for the iOS notification center.
“But what is NativeScript?”, you would ask. For those that do not know:
NativeScript is a framework for building cross-platform native mobile applications. You can write one source code and to reuse it on iOS and Android. But in order to be flexible and to be able to fully use the power of the native platform sometimes you need to add platform specific code to achieve a really shiny mobile application. In the light of our promise to have access to the entire native API and to support platform-specific code in NativeScript we want to show you how you can implement rich iOS specific notifications in your NativeScript app.
Our widget will use the native Chart component that ships with UI for NativeScript. The component will display static data (for simplicity) from the TIOBE index. Note that we will use the NativeScript CLI for this project.
At the end of this article you can see the running application.
> Note: Creating an iOS Today widget in NativeScript currently involves working in Xcode, but we're thinking through ways of allowing these types of extensions without the Xcode requirement. If you're interested, please vote for this feature and let us know your use cases in this issue on GitHub.
Assuming that you have installed NativeScript CLI, let’s dive in into the concrete steps of creating our project today.
To create a project and add the necessary iOS platform to it, execute the following commands in the terminal:
tns create sample-ios-todaywidget
tns platform add ios
tns prepare ios
UI for NativeScript is available as an npm package, so make sure you are at the main directory of your application (sample-ios-todaywidget) and execute the command below to install the product:
npm i nativescript-telerik-ui --save
This will install UI for NativeScript and will place the iOS library of interest (namely, the TelerikUI.framework) that contains the Chart component at
sample-ios-todaywidget/node_modules/nativescript-telerik-ui/platforms/iOS/TelerikUI.framework and also at sample-ios-todaywidget/lib/iOS/TelerikUI.framework .
Note that we are using the flag --save. Thanks to it, npm records this dependency in your app's package.json. If you open your package.json, you should now see nativescript-telerik-ui in your app's "dependencies" array.
> Tip: By saving your app's npm dependencies in your package.json file, you can always regenerate your node_modules folder by running npm install. Because of this, it's a common practice to exclude the node_modules folder from source control. The sample-ios-todaywidget application uses git for source control, and as such includes node_modules/ in its .gitignore.
> Note: UI for NativeScript is a commercial product and the Chart component that we take from npm is a Trial version. The non-Trial version will be available for sale soon. The SideDrawer component included in UI for NativeScript is completely free though.
Open the Xcode project at platforms/ios/sampleiostodaywidget.xcodeproj in Xcode.
In the General section, scroll down to the Embedded Binaries section. Click the “+” button and navigate to the platforms/ios/NativeScript.framework to add a reference to it. The NativeScript.framework provides the NativeScript runtime.
The NativeScript.framework is a shared framework that will be used both by the app and the extension. At the end, the app with the widget will be smaller in size (about a megabyte), because of the single library shared between the two targets.
Navigate to the TodayWidget target’s General section and in the Link Binary With Libraries add a reference to the the platforms/ios/NativeScript.framework.
From the sampleiostodaywidget target's Build Phases copy Generate Metadata to the TodayWidget target's Build Phases. Here is how to do that:
In order to add a reference to the iOS Chart component that stays behind the Chart wrapper of UI for NativeScript, do the following:
Navigate to the sampleiostodaywidget target's General tab.
Click the “+” button of Linked Frameworks and Libraries
Select the TelerikUI.framework from sample-ios-todaywidget/node_modules/nativescript-telerik-ui/platforms/TelerikUI.framework or from the directory that was created to contain the native library of UI for NativeScript: sample-ios-todaywidget/lib/iOS/TelerikUI.framework .
Add the TelerikUI.framework folder to Framework Search Paths in Build Settings".
Add the following flags to Build Settings -> Other Linker Flags:
-sectcreate __DATA __TNSMetadata "$(CONFIGURATION_BUILD_DIR)/metadata-$(CURRENT_ARCH).bin" $(inherited)
From the left navigation pane, navigate to TodayWidget/SupportingFiles and delete the files:
In the TodayWidget/Supporting Files/Info.plist, replace the NSExtensionMainStoryboard property set to MainInterface, with NSExtensionPrincipalClass property set to TodayViewController. The result should look like:
Insert the following bootstrapping code there:
Create a new file in your app directory and name it tiobe-widget.ios.js. During compilation for iOS only this file will be moved to platforms/ios/sampleiostodaywidget/app, with the 'ios' suffix stripped.
Basically, we are first creating a column chart filling it with some static data, and setting the appropriate axis styles. At the bottom, we define the principal class we set in the TodayWidget’s Info.plist:
This is all for the implementation. Now run the following command at the root of your NativeScript project:
tns prepare ios
Open the Xcode project in platforms/ios. Select the TodayWidget target at the top left of the Xcode window and an appropriate simulator. Click the 'build and run' button. You will be asked which app to run, select Today, and click Run.
Below you can see how our widget will look. Draw the Notification Center from the top, then click the Edit button and add our brand new TodayWidget to the list of the available widgets.