You are on page 1of 16

NATURAL LANGUAGE PROCESSING — IOS

Build a Positive News iOS Application Using


the Power of Machine Learning
How you can create your own positive news iOS application

Omar M’Haimdat
Jun 5, 2020 · 9 min read

Photo by MI PHAM on Unsplash

Since the beginning of the coronavirus pandemic, the news has been overwhelmingly
negative and somewhat depressing. You open Twitter or your favorite news
application, and you’re left with loads and loads of information that can drain your
energy.

In a world saturated with information, more and more people are choosing to offer
positive news, even if it’s still often confined to a specific section.

For example, The British daily newspaper The Guardian offers “The Upside”, while Fox
News, MSN, the HuffPost site, and Yahoo! all have “good news” pages.

Figure 1: Google trends for “good news” (red) and “positive news” (blue) in the USA

The most surprising lesson of this crisis is probably the need for people to access ‘good’
news. Google trends data shows a spike of interesting queries (Figure 1) such as good

news or positive news during the months of March and April.

The data shows that this is also the case in multiple regions (Europe, India…).
Figure 2: Google trends for “good news” (red) and “positive news” (blue) Worldwide

After seeing this, I decided that I might be able to choose what kinds of information to
consume in order to break the chain of negativity. I’m a developer so I thought, why not
create an application that’ll select only positive news and remove negative and neutral
ones for me?

With recent advances in natural language processing (NLP) and mobile processing, we
can select, with a certain level of accuracy, the most positive news and create our own
custom feeds.

In this article, I’ll create an iOS application that will consume an API and select the
most positive articles.

Some of the most engaging mobile apps have a


secret ingredient…Machine learning. Discover
what’s possible with this cutting-edge technology
in our newest (free) ebook, which explores 14 real-
world use cases for mobile ML.

Overview
1. Find the right news API

2. Create our iOS application

3. Create a decodable to parse the API calls

4. Customize the feed view

5. Final results and possible improvements

I have included code in this article where it’s most instructive. Full code and data can
be found on my GitHub page. Let’s get started.

omarmhaimdat/positive_newsfeed
How You Can Effortlessly Create Your Own Positive News iOS
Application The project consists of an iOS application that…
github.com

This is a look at what the final result will look like:


Figure 3: final result

Find the right news API


In order to get a stream of articles, we need to find a good API that will get us articles
from various sources. These articles will be used to create our custom news feed. The
simplest one is News API — you can customize the API calls and get articles related to a
specific country or/and a specific topic.

I chose to get top and breaking news headlines from the United States curated in an
API called “Top headlines from the United States”, but you can choose whatever topic
interests you.

You do need to create an account to get an apiKey , and the rest is pretty

straightforward. You choose the “News sources” and the subcategory, and the website
will then generate a GET URL with the appropriate key and news sources.

You can easily test your link in your browser and understand the structure of the API
call:
Figure 4: API request status

The API call is structured as such:

error : Indicates whether the request was successful or not—“ok” for a successful

request, and an “error” for a problem.

totalResults : Number of articles

articles : An array of articles


Figure 5: news article API structure

Create our iOS application


Create a new “Single View Application” and make sure you choose Storyboard as User
Interface.

Figure 6: create a new iOS project

Now we have our project ready to go. I don’t like using storyboards myself, so the app
in this tutorial is built programmatically, which means no buttons or switches to toggle
— just pure code.

To follow this method, you’ll have to delete the main.storyboard file and set your
SceneDelegate.swift file (Xcode 11 only).

With Xcode 11, you’ll have to change the Info.plist file like so:
Figure 7: delete the Storyboard Name from the .plist file

You need to delete the “Storyboard Name” in the file, and that’s about it.

Change the SceneDelegate with the following code:

1 var window: UIWindow?


2
3 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions:
4 guard let windowScene = (scene as? UIWindowScene) else { return }
5
6 window = UIWindow(frame: windowScene.coordinateSpace.bounds)
7 window?.windowScene = windowScene
8 window?.rootViewController = ViewController()
9 window?.makeKeyAndVisible()
10 }

SceneDelegate.swift
hosted with ❤ by GitHub view raw

Create View Controllers


We need two ViewControllers:

ViewController() :

This is where we’ll set our UICollectionView with all the articles retrieved from the
news API.

DetailsViewController() :
This is where we will show the article’s body.

Create a navigation
MainTabBarController() :

This is our main navigation, where we’ll create the full navigation structure for our
application.

Navigation in iOS is pretty straightforward and easy to implement. Here, I’ve changed
some things like the color and icon for the navigation bar (and others) so it looks nice.

AI-powered mobile apps sound exciting…but how


do they work, and how can they help scale your
business? Subscribe to the Fritz AI Newsletter for
answers to these questions and more.

Create a decodable to parse the API calls


Starting with Swift 4, we can create a representation of an API call using a struct and
conforming it to the Decodable protocol. The protocol only works when you read JSON
data.

The API returns a series of elements that could be parsed using two important
structures. The first one will mimic the API call upper node with a status ,

totalResult , and finally articles , which is an array of articles. The other one will

abstract a representation of an article, and thus will be used to create the array of
articles.

Here the structure of the Article struct:


Now that we have defined the properties of an Article , we create the ultimate API
call object Articles :

Both structures conform to the Decodable protocol. And the former is using the first
one to create an array of Article . Make sure that the properties' names are the exact

same as the API call.

Customize the feed view


Next we will need to customize our feed by adding a UICollectionView that will host
our articles.

Create a UICollectionView :

The news feed will have a stream of articles, we will use UICollectionView() that will
be instantiated in ViewController() with the following code:

Create an object of type UICollectionView()

Set the scroll direction

Change the background color

Toggle the Collection View to be constrained using auto layout

Then, we need to register the cells and set the data source, as well as set up the
ViewController() to conform to the UICollectionView() protocol:

Finally, we need to add the UICollectionView to the subview and set up the layout:

Add the collection to the subview of the UIViewController()

Change the background color to be compatible with Dark Mode

The final step, which is the conformance to UICollectionViewDataSource and


UICollectionViewDelegate , is available in the GitHub repository. In this part we will

feed the collection view with the data.


Create a custom UICollectionViewCell :

The collection is made up of cells that are members of the feed, think of it as Medium’s
homepage, UICollectionViewCell is an instance of an article, and the homepage is the
UICollectionView — each cell will have a title, author name and will also lead to the
full article. Thus, the homepage is a ‘Collection’ of articles.

I’m using a package made by Paolo Cuscela called Cards that mimics the iOS app store.

Figure 8: Cards pod package

For the sake of simplicity, I manually included the files in the project and created a new
Class that conforms to the CardDelegate protocol. The Class is also included in the
GitHub repository.

Figure 9: custom Card design

1 class CustomCell: UICollectionViewCell, CardDelegate {


2
3 var card: CardArticle!
4 var article: Article!
5
6 override init(frame: CGRect) {
7 super.init(frame: frame)
8 self.card = setupCardTest() as? CardArticle
9 self.card.delegate = self
10 self.article = Article(author: "", title: "", description: "", url: "", publishedAt: ""
11 }
12
13 func setupCardTest() -> Card {
14
15 let screenSize = UIScreen.main.bounds
16 let screenHeight = screenSize.height
17 let card = CardArticle(frame: CGRect(x: 30, y: 140, width: self.frame.width - 32 , heig
18 self.addSubview(card)
19 card.translatesAutoresizingMaskIntoConstraints = false
20
21 switch UIScreen.main.nativeBounds.height {
22 case 1136:
23 //iPhones_5_5s_5c_SE
24 card.heightAnchor.constraint(equalToConstant: screenHeight/2.5).isActive = true
25 card.topAnchor.constraint(equalTo: self.topAnchor, constant: 15).isActive = true
26 card.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20).isActive =
27 case 1334:
28 //iPhones_6_6s_7_8
29 card.heightAnchor.constraint(equalToConstant: screenHeight/2.5).isActive = true
30 card.topAnchor.constraint(equalTo: self.topAnchor, constant: 15).isActive = true
31 card.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20).isActive =
32 case 1792:
33 //iPhone_XR
34 card.heightAnchor.constraint(equalToConstant: screenHeight/3).isActive = true
35 card.topAnchor.constraint(equalTo: self.topAnchor, constant: self.frame.height/5 -
36 case 1920, 2208:
37 //iPhones_6Plus_6sPlus_7Plus_8Plus
38 card.heightAnchor.constraint(equalToConstant: screenHeight/2.5).isActive = true
39 case 2436:
40 //iPhones_X_XS
41 card.heightAnchor.constraint(equalToConstant: screenHeight/3).isActive = true
42 card.topAnchor.constraint(equalTo: self.topAnchor, constant: self.frame.height/5 -
43 case 2688:
44 //iPhone_XSMax
45 card.heightAnchor.constraint(equalToConstant: screenHeight/2.5).isActive = true
46 default:
47 card.heightAnchor.constraint(equalToConstant: screenHeight/4).isActive = true
48 card.topAnchor.constraint(equalTo: self.topAnchor, constant: self.frame.height/5 -
49 }
50
51 card.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
52 card.widthAnchor.constraint(equalToConstant: self.frame.width - 32).isActive = true
53 card.backgroundColor = .systemBackground
54 card.subtitle = ""
55 card.title = "titre"
56 card.category = "author"
57 card.textColor = UIColor.black
58 card.hasParallax = false
59 return card
60 }
61
62 override func prepareForReuse() {
63 self.card.title = "titre"
64 self.card.subtitle = ""
65 self.card.category = "author"
66 self.card.textColor = UIColor.white
67 }
68
69 required init?(coder aDecoder: NSCoder) {
70 fatalError("init(coder:) has not been implemented")
71 }
72 }

Here’s a breakdown of the CustomCell() our UICollectionViewCell() :

First, we need to instantiate an object of type CardArticle which will be the design
structure of the cell

Then an object of type Article that contains the data

Create an initializer where we initialize the Card and the Article object

Create a function that will set up the Card’s bounds and attributes (title, author,
background color, text color and many more)

Finally, we need to override an important function that gets invoked every time a
cell is reused by the UICollectionView() . This function exists to improve the
efficiency and the performance of the feed. Thus, when a cell is not visible on the
screen, the collection view dequeues it and remove it from the stack.

Predict and populate the feed


Since iOS 13, Apple has included in its NaturalLanguage framework the ability to
leverage a built-in solution without any external resource.
This feature, more broadly, is known as sentiment analysis, and it gives you the power
to access the general sentiment in a given word, sentence, paragraph, or document.
The sentiment score is structured as a float number that can range from -1.0 to 1.0. A
score of 1.0 is the most positive, a score of -1.0 is the most negative, and a score of
0.0 is neutral.

Since we only want positive text, we’ll only surface articles that have a score strictly
above 0.

Here’s a break down of the code:

Instantiate a NLTagger and choose sentimentScore as an option.

Set the object’s string by passing the input text.

Run inference by calling the method tag() , specifying that the text is a paragraph

for better prediction.

Parse the output as a Double .

Test the output and set the final score if the text is positive ( 1 ), negative ( 0 ) or
neutral ( -1 ).

Before loading the CollectionView , we’ll run inference on each and every article’s text.

Final results and possible improvements


The application calls an API and only shows the most positive articles. Unfortunately,
the News API is not free and only returns a portion of articles. Thus, there are a
number of possibilities for improving the overall experience by adding or modifying
the following elements:

Create your own API by scraping and parsing your own favorite news outlet, which
will help you customize your feed even more.

Create your own custom NLP model using state-of-the-art architectures such as
Transformer GPT-2 or BERT. In these cases, the model will perform the inference
on the server-side rather than on-device. I wrote an article that can help you get
started with sentiment analysis using Transformers.

Improve the overall experience by running inference in backend while scraping


and parsing articles.

Add a section for the most important and breaking news articles in order to stay up
to date.

Setup a notification system in order to receive intermittent news alerts.

Add a share functionality to spread positivity around you 😃

The Internet is full of positive news, you just need to search harder on the various news
sites and you will find good news. By using your coding skills you can leverage the
power of ML and programming and totally automate the process. The news feed can
also cover subjects that you deem important, as long as the news fits your own
expectations.

Thanks for reading this article. If you have any questions, don’t hesitate to send me an
email at omarmhaimdat@gmail.com.

This project is available to download from my GitHub account:

omarmhaimdat/positive_newsfeed
How You Can Effortlessly Create Your Own Positive News iOS
Application The project consists of an iOS application that…
github.com

Editor’s Note: Heartbeat is a contributor-driven online publication and community


dedicated to exploring the emerging intersection of mobile app development and machine
learning. We’re committed to supporting and inspiring developers and engineers from all
walks of life.
Editorially independent, Heartbeat is sponsored and published by Fritz AI, the machine
learning platform that helps developers teach devices to see, hear, sense, and think. We pay
our contributors, and we don’t sell ads.

If you’d like to contribute, head on over to our call for contributors. You can also sign up
to receive our weekly newsletters (Deep Learning Weekly and the Fritz AI Newsletter),
join us on Slack, and follow Fritz AI on Twitter for all the latest in mobile machine
learning.

Machine Learning Positive Thinking iOS App Development Programming Heartbeat

About Write Help Legal

Get the Medium app

You might also like