![]() |
In app.js we have set up already two routes for the news section: tab.news and tab.details. On the first one we will see all news. Tapping on each of them will open view page with the news details.
News list
- <!-- www/templates/tab-news.html -->
- <ion-view view-title="Good News">
- <ion-content>
- <ion-refresher
- pulling-text="Pull to refresh..."
- on-refresh="refresh()">
- </ion-refresher>
- <ul class="list">
- <li class="item" ng-repeat="n in news" ui-sref="tab.details({id: n._id})">
- {{n.text}}
- </li>
- </ul>
- </ion-content>
- </ion-view>
- // www/js/controllers.js
- ...
- .controller('NewsCtrl', function ($scope, NewsService, $ionicLoading) {
- $ionicLoading.show({
- template: 'Loading...'
- });
- NewsService.all().then(function (news) {
- $scope.news = news;
- $ionicLoading.hide();
- });
- $scope.refresh = function () {
- NewsService.all().then(function (news) {
- $scope.news = news;
- $scope.$broadcast('scroll.refreshComplete');
- });
- };
- })
- ...
- <!-- www/templates/details.html -->
- <ion-view view-title="Good News">
- <ion-content>
- <div class="card">
- <div class="item item-divider">
- {{news.createdAt | date : fullDate}}
- </div>
- <div class="item item-text-wrap">
- {{news.text}}
- </div>
- <div class="item item-divider">
- by {{news.username}}
- </div>
- </div>
- </ion-content>
- </ion-view>
- // www/js/controllers.js
- ...
- .controller('DetailsCtrl', function ($scope, $state, NewsService,
- $ionicLoading) {
- $ionicLoading.show({
- template: 'Loading...'
- });
- var id = $state.params.id;
- NewsService.one(id).then(function (news) {
- $scope.news = news;
- $ionicLoading.hide();
- });
- })
- ...
- // www/js/newsService.js
- (function () {
- function _NewsService($q, config, $http) {
- function getOne(id) {
- var deferred = $q.defer();
- $http.get(config.server + '/news/' + id)
- .success(function (data) {
- if (data.error || !data.news) {
- deferred.reject(data.error);
- }
- deferred.resolve(data.news);
- })
- .error(function () {
- deferred.reject('error');
- });
- return deferred.promise;
- }
- function getAll() {
- var deferred = $q.defer();
- $http.get(config.server + '/news')
- .success(function (data) {
- if (data.error || !data.news) {
- deferred.reject(data.error);
- }
- deferred.resolve(data.news);
- })
- .error(function () {
- deferred.reject('error');
- });
- return deferred.promise;
- }
- return {
- one: getOne,
- all: getAll
- };
- }
- _NewsService.$inject = ['$q', 'Config', '$http'];
- angular.module('app.services')
- .factory('NewsService', _NewsService);
- })();
- Server side (news)
- <!-- adminpanel/add-news.html -->
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>Add News</title>
- </head>
- <body>
- <form action="/news" method="post">
- <h2>Add good news</h2>
- <p>
- <textarea name="text" cols="50" rows="10"
- placeholder="News body"></textarea>
- </p>
- <p>
- <input type="text" required name="username"
- placeholder="Username"/>
- </p>
- <p>
- <button type="submit">Add news</button>
- </p>
- </form>
- </body>
- </html>
- // server.js
- ...
- app.use(express.static(__dirname + '/adminpanel'));
- app.get('/add-news', function (req, res) {
- res.sendFile(__dirname + '/adminpanel/add-news.html');
- });
- ...
![]() |
- // models/news.js
- var mongoose = require('mongoose');
- var Schema = mongoose.Schema;
- module.exports = function () {
- 'use strict';
- var NewsSchema = new Schema({
- username: String,
- text: String,
- createdAt: {type: Date, default: Date.now}
- });
- mongoose.model('News', NewsSchema, 'News');
- };
- // routes/news.js
- var mongoose = require('mongoose');
- var News = mongoose.model('News');
- var Users = mongoose.model('Users');
- var apn = require('apn');
- var _ = require('lodash');
- module.exports = function (app) {
- 'use strict';
- var router = app.get('router');
- router.get('/news', function (req, res) {
- News.find().sort({createdAt: -1}).lean().exec(function (err, news) {
- if (err) {
- return res.json({error: err});
- }
- res.json({error: null, news: news});
- });
- });
- router.get('/news/:id', function (req, res) {
- var id = req.params.id;
- News.findById(id).lean().exec(function (err, news) {
- if (err) {
- return res.json({error: err});
- }
- res.json({error: null, news: news});
- });
- });
- router.post('/news', function (req, res) {
- var username = req.body.username;
- var text = req.body.text;
- var news = new News({
- username: username,
- text: text
- });
- news.save(function (err, news) {
- process.nextTick(function () {
- sendPush(news);
- });
- res.redirect('/add-news');
- });
- });
- function sendPush(news) {
- var text = news.text.substr(0, 100);
- Users.find({deviceRegistered: true}).lean().exec(function (err, users) {
- if (!err) {
- for (var i = 0; i < users.length; i++) {
- var user = users[i];
- var device = new apn.Device(user.deviceToken);
- var note = new apn.Notification();
- note.badge = 1;
- note.contentAvailable = 1;
- note.alert = {
- body : text
- };
- note.device = device;
- var options = {
- gateway: 'gateway.sandbox.push.apple.com',
- errorCallback: function(error){
- console.log('push error', error);
- },
- cert: 'PushNewsCert.pem',
- key: 'PushNewsKey.pem',
- passphrase: 'superpass',
- port: 2195,
- enhanced: true,
- cacheLength: 100
- };
- var apnsConnection = new apn.Connection(options);
- console.log('push sent to ', user.username);
- apnsConnection.sendNotification(note);
- }
- }
- });
- }
- };
Push notification will be sent, but how app will know about it? We must add an event listener to the app.js
- // www/js/app.js
- ...
- .run(function ($ionicPlatform, $rootScope) {
- $ionicPlatform.ready(function () {
- $rootScope.$on(
- '$cordovaPush:notificationReceived',
- function (event, notification) {
- if (notification.alert) {
- navigator.notification.alert(notification.alert);
- }
- });
- });
- })
- ...
For using push notifications in our app, we have to prepare the App ID, SSL Certificate and create Provisioning Profile in iOS Dev Center.
Create Certificate
Open Keychain Access on your mac and choose Request a Certificate from a Certificate Authority...
![]() |
![]() |
![]() |
Select Identifiers in the iOS Apps section.
Go to App IDs in the sidebar and click the "+" button.
![]() |
Enter App ID registration data:
- App ID Description / Name - PushNews
- Explicit App ID / Bundle ID - com.your_domain.PushNews (this ID and cordova app name should be the same)
- App Services / Enable Services - Push Notifications
Press Continue and Submit.
Now we have to set up our app. Select PushNews in Apps IDs list and press Edit in the bottom.
Find Push Notifications section and press Create Certificate... in the Development SSL Certificate section.
![]() |
Press Continue and Choose PushNews.certSigningRequest created early, press Generate
Download generated certificate and save it as aps_development.cer
Making PEM files
Go to the directory where you've saved files and run these commands in Terminal for converting:
.cer file into a .pem
- $ openssl x509 -in aps_development.cer -inform der -out PushNewsCert.pem
.p12 into a .pem
- $ openssl pkcs12 -nocerts -in PushNewsKey.p12 -out PushNewsKey.pem
You will be asked to enter your passphrase for .p12 file and new pass for .pem file. Copy both .pem files to the app's root directory.
Making the Provisioning Profile
Let's return to iOS Dev Center. Click the Provisioning Profiles/Development in the sidebar and click the "+" button.
- Choose iOS App Development
- Select PushNews App in App ID list
- Select your certificate
- Select devices you want to include in this provisioning profile
- Enter Profile Name (I will use "PushNews Development")
Press Generate and download profile when it will be created, we will use it later.
![]() |
Let's change cordova id in config.xml (by default it will be something like com.ionicframework.PushNews456803) to Explicit App ID / Bundle ID value you have entered above (com.your_domain.PushNews).
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <widget id="com.telnov.PushNews" version="0.0.1" xmlns="http://www.w3.org/ns/widgets"
- xmlns:cdv="http://cordova.apache.org/ns/1.0">
- <name>pushNews</name>
- ...
Test on device
OK, now you can check result. To launch app on iOS device, we have to add ios platform first:
- $ ionic platform add ios
- $ ionic build ios
At the first time, when you are trying to launch any application that use push notifications, you should give an access, so after you entering twitter credentials, you will see popup
![]() |
Try adding news and enjoy the results.
![]() |
Conclusion
We have created the project, which demonstrates how easy you can build iOS applications using web technologies only.
Written by Oleksandr Telnov
If you found this post interesting, follow and support us.
Suggest for you:













No comments:
Post a Comment