Display now playing information in Command Center

Previously, I covered an article Configure Audio Session for background audio mode (iOS Project). Next step is to show relevant information in Command Center for audio played from your iOS Application.

Let’s start by importing MediaPlayer

import MediaPlayer

Next, place the following code to set now playing information

let image = UIImage(named: "artwork")!
let mediaArtwork = MPMediaItemArtwork(boundsSize: image.size) { (size: CGSize) -> UIImage in
  return image
}

let nowPlayingInfo: [String: Any] = [
  MPMediaItemPropertyArtist: "hashaam.com",
  MPMediaItemPropertyTitle: "Live Streaming Example",
  MPMediaItemPropertyArtwork: mediaArtwork,
  MPNowPlayingInfoPropertyIsLiveStream: true
]

MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo  

Notice, setting the MPNowPlayingInfoPropertyIsLiveStream to true will show LIVE status in Command Center.

This gives required information to be displayed in Command Center
Display now playing information in Command Center

And also in the lock screen
Display now playing information in Lock Screen

Here is gist for the example

Configure Audio Session for background audio mode (iOS Project)

We use AVPlayer from AVFoundation to play audio in our applications. The moment we send the application to back ground mode, audio stops playing.

To fix this, we will need to configure AVAudioSession properly. We start by importing AVFoundation in AppDelegate or our iOS Project.

import AVFoundation

Next, add the following code in application didFinishLaunchingWithOptions:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // enable playback category: this is required for background audio to function normally
    let audioSession = AVAudioSession.sharedInstance()
    try? audioSession.setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault)
    try? audioSession.setActive(true, with: [])
    
    return true
}

Finally, enable Background Audio Mode in Project Settings.
Enable background audio mode in XCode Project Settings

Here is gist for the example

Strip HTML tags in Swift

There are many cases where we need to clean out text from an HTML source. Many people have solved this in their own way. But I have come across a simple solution to this problem. The solution was to use NSAttributedString with setting NSDocumentTypeDocumentAttribute to NSHTMLTextDocumentType.

Let’s start with the following HTML:

let htmlString = "LCD Soundsystem was the musical project of producer <a href='http://www.last.fm/music/James+Murphy' class='bbcode_artist'>James Murphy</a>, co-founder of <a href='http://www.last.fm/tag/dance-punk' class='bbcode_tag' rel='tag'>dance-punk</a> label <a href='http://www.last.fm/label/DFA' class='bbcode_label'>DFA</a> Records. Formed in 2001 in New York City, New York, United States, the music of LCD Soundsystem can also be described as a mix of <a href='http://www.last.fm/tag/alternative%20dance' class='bbcode_tag' rel='tag'>alternative dance</a> and <a href='http://www.last.fm/tag/post%20punk' class='bbcode_tag' rel='tag'>post punk</a>, along with elements of <a href='http://www.last.fm/tag/disco' class='bbcode_tag' rel='tag'>disco</a> and other styles. "

Below is a working example:

let htmlStringData = htmlString.data(using: String.Encoding.utf8)!

let options: [String: Any] = [
    NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
    NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue
]

let attributedString = try! NSAttributedString(data: htmlStringData, options: options, documentAttributes: nil)

let stringWithoutHTMLTags = attributedString.string

This process is slower when working on a long HTML source. Which can be easily offloaded onto a background process:

let htmlStringData = htmlString.data(using: String.Encoding.utf8)!

let options: [String: Any] = [
    NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
    NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue
]

DispatchQueue.global(qos: .userInitiated).async {

    // perform in background thread
    let attributedString = try! NSAttributedString(data: htmlStringData, options: options, documentAttributes: nil)

    DispatchQueue.main.async {
        // handle text in main thread
        let stringWithoutHTMLTags = attributedString.string
    }

}

 

Also in gist:

Source: Stack Overflow

Working with live views in Swift Playground

Prototype faster in Swift Playground without Projects

When working on prototypes it is easy to create a new Playground to experiment on views. This makes the development really fast and easy. This method is much faster than creating a new XCode Project for prototyping.

Below is the code I use in Swift Playground


import UIKit
import PlaygroundSupport

let f = CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0)
let v = UIView(frame: f)
v.backgroundColor = UIColor.yellow

PlaygroundPage.current.liveView = v

 

Then, to see the live view, select ViewAssistant EditorShow Assistant Editor

Show Assistant Editor in XCode

 

And then select Timeline option to see the live view.

Show Playground Timeline in Assistant Editor (XCode)

 

Later, we will add UIView with red background color as sub-view to test live updates.


// will be adding red view as sub view
let redView = UIView(frame: CGRect.zero)
redView.translatesAutoresizingMaskIntoConstraints = false
redView.backgroundColor = UIColor.red

v.addSubview(redView)

redView.centerXAnchor.constraint(equalTo: v.centerXAnchor, constant: 0.0).isActive = true
redView.centerYAnchor.constraint(equalTo: v.centerYAnchor, constant: 0.0).isActive = true
redView.widthAnchor.constraint(equalToConstant: 15.0).isActive = true
redView.heightAnchor.constraint(equalToConstant: 15.0).isActive = true

 

And finally, see the updates.

See live updates in Playground (XCode)

Adding https support in Flask

Getting a chance to work on Python, my favorite framework is Flask (http://flask.pocoo.org/). It is a micro-framework that lets you create and deploy APIs, websites, and dashboards.

When deploying Flask projects onto a production server, we need to only support HTTPS and redirect HTTP requests to HTTPS. This creates a problem with Flask url_for function, which only outputs HTTP URLs.

Below is one way to achieve this. Following is taken from my production deployment.

import os
from flask import Flask

app = Flask(__name__)

@app.before_request
def before_request():
    if os.environ["PROJECT_ENV"] != "dev":
        from flask import _request_ctx_stack
        if _request_ctx_stack is not None:
            reqctx = _request_ctx_stack.top
            reqctx.url_adapter.url_scheme = "https"

if __name__ == "__main__":
    app.run(port=80, host="0.0.0.0")

 

Update: 8 June 2017

I have found another way of adding https support to flask.

from flask import Flask

class ReverseProxied(object):
        def __init__(self, app):
                self.app = app

        def __call__(self, environ, start_response):
                environ['wsgi.url_scheme'] = 'https'
                return self.app(environ, start_response)

app = Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)

if __name__ == "__main__":
    app.run(port=80, host="0.0.0.0")

This was mentioned in stack overflow post:

https://stackoverflow.com/a/37842465

Let me know if you have a better approach to this problem.

Noto Fonts: Beautiful and free fonts for all languages

Google has provided and open-sourced Noto fonts family covering all the languages. The complete font package is over 100MB, which can be downloaded as one or individual fonts.

I have recently used Noto Kufi Arabic font in Al Arabiya News (Arabic) iOS Application. Check out how neat and readable the text renders.


To find out more and check out other fonts, head over to https://www.google.com/get/noto/ .

Generate Random Colors in Swift

Randomize UIColor

We have all come across scenarios where we need to use random colors. For example, showing UIViewControllers with random background color in a UIPageViewController, or just show UITableViewCells with random background colors in a UITableView.

I have created an extension on UIColor to help me in the applications.

Here is the code in Swift 3:

extension UIColor {
    static var random: UIColor {
        // Seed (only once)
        srand48(Int(arc4random()))
        return UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0)
    }
}

 

Usage:

view.backgroundColor = UIColor.random

 

Here is the github repo for the sample project:

https://github.com/hashaam/Sample-RandomColor