iOS Archives — Now Playing Apps https://nowplayingapps.com/category/ios/ Let's build it together Sun, 22 Mar 2020 02:32:46 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 151952093 Better iOS ratings and reviews using SKStoreReviewController https://nowplayingapps.com/ios-rating-and-review-prompt-using-skstorereviewcontroller/ Sun, 22 Mar 2020 02:04:28 +0000 https://nowplayingapps.com/?p=333 Learn how to implement iOS Rating and Review prompt along with some best practices to maximize positive feedback from your audience

The post Better iOS ratings and reviews using SKStoreReviewController appeared first on Now Playing Apps.

]]>
The iOS app store has millions of apps for each category and as a developer, it is hard to stand out even if you provide great functionalities. Positive ratings and reviews are the major factors that impact the discoverability of your app in the app store. Apple provides a great way to collect positive (or negative) feedback directly from your users right inside the app using iOS rating and review prompt. Let’s see how.

Apple has provided an easy way to request ratings and reviews from your audience. This StoreKit API called SKStoreReviewController has a static function called requestReview() that will display an iOS rating and review prompt to collect the feedback. Here’s how we trigger it:

import StoreKit

@available(iOS 10.3, *)
class RatingManager {

    static func displayRatingPrompt() {
        SKStoreReviewController.requestReview()
    }
    
}

This API works only on iOS 10.3 and above. For iOS versions prior to this, please see the manually requesting a review section. Also, be sure to check out the best practices for displaying iOS rating and review prompt.

Review prompt will still display even in development mode or builds that are distributed through TestFlight for testing purposes, but will not affect the App Store rating or reviews.

Using UserDefaults to control the frequency of iOS rating and review prompt

You also need to be aware that this modal will only get presented to a maximum of 3 times in a year (or 365 days period). So deciding when and where the modal should appear should be chosen carefully. Here are some utility functions to be added to your RatingManager class to help us with it:

private static let promptDisplayLimitPerVersion = 3
private static let promptCounterKey = "RatingReviewPromptDisplayCounter"
private static let promptLastDisplayedVersionKey = "RatingReviewPromptLastDisplayedKey"

/// returns current app version in string format
private static func currentAppVersion() -> String {
    let currentVersion = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String
    return currentVersion ?? ""
}

/// every time rating prompt is shown to the user, it will be persisted in user defaults
/// this function returns the app version in which rating prompt is last shown to the user.
private static func lastRatingPromptDisplayedAppVersion() -> String {
    let lastDisplayedVersion = UserDefaults.standard.string(forKey: promptLastDisplayedVersionKey)
    return lastDisplayedVersion ?? ""
}

/// set current version of the app as the last version
/// on which rating prompt was displayed
private static func setCurrentAsPromptDisplayedVersion() {
    UserDefaults.standard.set(currentAppVersion(), forKey: promptLastDisplayedVersionKey)
}

/// returns an integer that represents how many times rating prompt
/// is displayed to the user in the current version of the app
private static func displayCount() -> Int {
    return UserDefaults.standard.integer(forKey: promptCounterKey)
}

/// when a rating is prompted to the user, increment the counter
private static func incrementDisplayCount() {
    var count = displayCount()
    count += 1
    UserDefaults.standard.set(count, forKey: promptCounterKey)
}

/// reset the app display counter
private static func resetDisplayCount() {
    UserDefaults.standard.set(0, forKey: promptCounterKey)
}

and now changing the rating prompt initialization like this:

import StoreKit

@available(iOS 10.3, *)
class RatingManager {
    
    static func requestReviewIfNeeded() {
        let appVersionDidChange = currentAppVersion() == lastRatingPromptDisplayedAppVersion()
        let displayCountDidReachLimit = displayCount() >= promptDisplayLimitPerVersion
        
        if appVersionDidChange {
            // the app version has changed since the previous prompt is shown to the user
            // so it is safe to display the prompt `promptDisplayLimitPerVersion` times.
            resetDisplayCount()
        }
        
        if !displayCountDidReachLimit {
            displayRatingPrompt()
            incrementDisplayCount()
            setCurrentAsPromptDisplayedVersion()
        }
    }
    
    private static func displayRatingPrompt() {
        SKStoreReviewController.requestReview()
    }
    
    /// insert utility functions here...
}

Now, requestReviewIfNeeded is the only front-facing function for RatingManager and when you request for a rating prompt, it will take all the necessary checks into consideration.

Manually requesting a review

We have certain checks inside our RatingManager class to decide whether or not to display the rating prompt or not. However, you can manually take the user to the App Store review page when the user wishes to do so (say, if you have a “review this app” button in the settings). All you need to do at this time is to open your App Store URL.

/// Open App Store URL to request a manual review from the user
static func manualRequestAppReview(appId: String) {
    let appStoreURL = "https://itunes.apple.com/app/\(appId)?action=write-review"
    guard let reviewURL = URL(string: appStoreURL) else {
        return
    }
    
    UIApplication.shared.open(reviewURL, options: [:], completionHandler: nil)
}

Some best practices for iOS rating and review prompt

  1. Avoid showing rating and review modal as soon the user opens the app. This should be the case even if it is not the first time the user is opening your app.
  2. Let the user use the app for a couple of days (or maybe weeks), and only request a review after they get a chance to play with main functionalities.
  3. Ask for a review at the right time. Probably not a good idea to do so after they lost a game level or dismissed an ad.
  4. Give enough time interval between rating requests. A frequent request might work against you.

Adding a review prompt is also one of the top five features your app should have. To read more about all the essentials features of an app to succeed, please check out my blog post here.

Conclusion

As you just saw, it is very easy to get feedback from your users without having to do much work by using APIs provided by iOS. Implementing this feature following the best practices can help you collect positive feedback, which will translate to better visibility in the App Store.

The post Better iOS ratings and reviews using SKStoreReviewController appeared first on Now Playing Apps.

]]>
333
Handling audio interruptions in your iOS app https://nowplayingapps.com/handling-audio-interruptions-in-your-audio-app/ Mon, 10 Feb 2020 02:46:57 +0000 https://nowplayingapps.com/?p=304 Handling audio interruptions is key to improving user experience of your app. This article describes how to handle such interruptions gracefully

The post Handling audio interruptions in your iOS app appeared first on Now Playing Apps.

]]>
Interruptions are common in any type of software system. It is even more important in the case of mobile apps, starting with network interruptions to other common ones such as receiving calls or alarm notifications (also called audio interruption). Handling these audio interruptions will enhance the user experience gracefully.

Common types of audio interruptions

  1. Receiving incoming or making outgoing calls
  2. Alarm or timer notifications
  3. Other app takes over the iOS audio session (for example user opens a podcast app and starts playing it while your music app was playing)

How does the operating system handles interruption?

  1. Operating System deactivates your apps audio session
  2. Sends a notification through NSNotificationCenter saying an interruption has occurred. This will allow your app to gracefully respond to the interruption, for example, by pausing/stopping your playback and updating the UI states – such as display paused icon
  3. Once the interruption has ended, the operating system sends another notification confirming the interruption has ended. This will allow your app can respond to it (by resuming the playback and updating the UI state – display playing icon)

So basically, in order to handle these interruptions, all you need to do is listen to interruption notifications, and respond to it accordingly. Let’s see how.

Listening to audio interruption notifications

This can be done by adding an observer for AVAudioSession.interruptionNotification event.

private func addInterruptionsObserver() {
    NotificationCenter.default.addObserver(self,
                   selector: #selector(handleInterruption),
                   name: AVAudioSession.interruptionNotification,
                   object: nil)
}

Make sure that your app’s AVAudioSession is set before this observer is added.

How to gracefully handle audio interruptions

Once the observer is set, handleAudioInterruption will now receive notifications when an interruption begins and ends.

@objc private func handleInterruption(notification: Notification) {
    guard let userInfo = notification.userInfo,
        let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
        let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
            return
    }
    
    switch type {
    case .began:
        // pause audio
        // update player UI state to paused
        
    case .ended:
        //  resume audio playback
        // update player UI state to playing
        // set audio session
        
    default: break
    }
}

If the AVAudioSession.InterruptionType == .ended, there may also be extra info inside the userInfo dictionary called AVAudioSession.InterruptionOptions which has a static property called shouldResume. This tells you whether your app is ready to be resumed.

guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else {
    return
}

let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue)
if options.contains(.shouldResume) {
    // Interruption Ended - playback should resume
}

And that’s it. Your app is now configured to handle audio interruptions gracefully.

Conclusion

Handling audio interruption is very essential to good user experience, and by listening to the events sent by iOS, it is an easy win for any media application.

The post Handling audio interruptions in your iOS app appeared first on Now Playing Apps.

]]>
304
Intelligent deeplink from Smart App Banner https://nowplayingapps.com/deep-link-from-smart-app-banner/ Sun, 18 Aug 2019 18:28:13 +0000 https://nowplayingapps.com/?p=256 Learn how to provide extra information as navigational context in the Smart App Banner to make the iOS app deeplink more seamless

The post Intelligent deeplink from Smart App Banner appeared first on Now Playing Apps.

]]>
Smart App Banner is an easy way to introduce your iOS app to your web traffic. The setup is very simple, and to learn more about getting started with Smart App Banner for iOS, check out the How to promote your iOS app with Smart App Banner article. Even though the basic setup is very straight forward, it would be wise to take it one step further and customize the banner by providing a bit more navigational context. This lets your users deeplink from the smart app banner to your app seamlessly from your website by reducing the friction as much as possible. Let’s take a look at what that means, and how it can be done.

Deeplink from smart banner app to it's equivalent page in iOS app
Deeplink from a webpage in Safari to the equivalent page in iOS app

Smart App Banner is enabled by adding a meta tag on your web page. We saw a few attributes in the basic setup article, and they were

name = “apple-itunes-app”
content = “app-id=app-id-of-your app”

Now, let us learn about a new key that goes into the “content” attribute, which is “app-argument”. An app-argument should be a valid URL that represents the current state of the website. For example, if your domain is example.com and you’re currently on the contact us page, the app-argument should be the URL that represents that particular page. If the URL is https://example.com/contact-us, the meta tag will look something like this:

<meta name="apple-itunes-app" content="app-id=myAppStoreID, 
app-argument=https://example.com/contact-us">

What are the advantages of providing an app-argument?

App-argument provides a way to pass additional context information to your iOS application. We can then parse the extra metadata from the app-argument and take the user directly to the equivalent page in-app. This provides continuity in experience between the web and the app. This continuity covers various use cases such as 

  1. passing the session info for a logged-in user, so that he/she can automatically be logged in inside the app
  2. transfer the search keyword, so that results are already populated when the app is opened
  3. provides full customization, as it is a URL, and can be parsed based on the unique requirement of the app.

How to receive this extra context inside your iOS app?

As mentioned earlier, the app-argument attribute should be a valid URL that corresponds to the current state on the web. This URL will be passed on to the application via the following AppDelegate method: 

func application(_ app: UIApplication, open url: URL, 
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool

Once you receive the URL, you can deconstruct the URL to figure out the state and navigate to the corresponding page/viewController in the app. For example,

let url = URL(string: "https://example.com/profile/john")!
print(url.pathComponents)
> ["/", "profile", "john"]

By looking at url.pathComponents, we can see that the user was viewing John’s profile on the web when he decided to switch to the app. And hence, the app opens John’s profile thereby making the transition seamless.

Conclusion

Providing a seamless deeplink from Smart App Banner is a great way to promote your iOS app and an improvement in the overall user experience.

The post Intelligent deeplink from Smart App Banner appeared first on Now Playing Apps.

]]>
256
How to promote your iOS app with Smart App Banner https://nowplayingapps.com/configure-smart-app-banner/ Sat, 17 Aug 2019 17:56:51 +0000 https://nowplayingapps.com/?p=221 Smart App Banner is an easy way to drive more engagement to your iOS app. Learn why it is important and how easy it is configure it on your website.

The post How to promote your iOS app with Smart App Banner appeared first on Now Playing Apps.

]]>
Have you ever noticed that when you visit some most popular websites (like PayPal or Trello), the Safari browser displays a beautifully laid out banner ad which contains a description of their iOS app and a call to action to download (if not installed) or view (if already installed) it? This is a feature is called Smart App Banner and is introduced in iOS 6 intended to promote your iOS app to users visiting your website and thereby driving more users to the mobile app. 

Advantages of Smart App Banner over a custom ad banner implementation

Of course, one may think that custom implementation of a similar banner would be an easy implementation on the server (web) side, but Smart App Banner offers many features that are very hard or may not even be possible to achieve.

  • Common look and feel across other products and hence won’t be mistaken as clickbait or spam advertisement
  • Clean presentation at the top without obstructing the main web content
  • Easy to get rid of, and once closed, it won’t re-appear on subsequent visits
  • Intelligently identify whether the app is installed, and thereby redirecting directly to the app instead of app store
  • If the app does not support the user’s device (due to minimum SDK version or location), the smart app banner won’t be displayed
  • Displays progress bar inside the banner to convey installation progress of the app from the app store

Alright, enough said about the benefits. Now, let us look at how to implement these smart app banners for your website and thereby giving a boost to your iOS app.

Implementing Smart App Banner

To get a Smart App Banner setup, you only need two things 

  1. Appstore id of your app
  2. Access to your web app backend

Step 1: Get Appstore id of your app

The easiest way to get the appId is to inspect the Appstore URL. Usually, appId will be appended towards the end of the URL. For example, in Canadian Appstore, Paypal URL is https://apps.apple.com/ca/app/paypal/id283646709 where “283646709” is the app id.

Getting App Id from App Store URL
App Id from App Store URL

However, this way of finding the appId from the App Store URL is not officially documented and may change any time in the future. Alternatively, you can locate the appId inside your iTunesConnect account under the App Information tab.

Getting App Id from iTunesConnect
App Id from iTunesConnect

Step 2: Add meta tag to your website.

Once you have your appId, we need to tell Safari that an in-market app is linked to this website. This is done by adding a meta tag inside the head tag of your website as shown below.

<meta name="apple-itunes-app" content="app-id=app-id-from-step1"/>

That’s it! When a new user comes to your site, Safari will identify your app in the app store and show the Smart App Banner.

What’s next?

There is also a provision to provide extra information in the meta tag in order to make seamless navigation to the iOS app. You can read more in the Intelligent deeplink from Smart App Banner article.

Conclusion

Smart App Banner is truly a smart way to increase traffic to your iOS app, and it takes care of many use cases on your behalf that you’ll have to manually implement on your website otherwise.

The post How to promote your iOS app with Smart App Banner appeared first on Now Playing Apps.

]]>
221
Five Essential Components for MVP Mobile App https://nowplayingapps.com/five-essential-components-mvp-app/ Sun, 31 Mar 2019 02:35:48 +0000 https://nowplayingapps.com/?p=211 Discuss from a technical stand point, the important features to include as part of your MVP app development.

The post Five Essential Components for MVP Mobile App appeared first on Now Playing Apps.

]]>
Alright, so you found this brilliant idea for your next app and decided to build the MVP (Minimum Viable Product). You would have thought out many new exciting features to make your audience fall in love with it. Despite all the amazing features that you have planned out, there are some key components that you can include which will help you better engage, measure and collect the audience feedback, and they are mostly available for free. Let’s take a look at the top 5 essential components, and see how you can take advantage of those in your MVP app.

The components I discuss here today revolves around different areas of customer engagement, mainly – Measure, Issue resolution, Communication and Feedback.

  1. Analytics
  2. Crash Reporting
  3. App update checker
  4. Review prompt
  5. Reachability

Analytics

The keyword here is Measurement. You probably have heard of the saying, “What gets measured, gets done”. Once you build experience in the form of a feature, or content or a visual asset inside your app, it is very important to see how your audience reacts to it. Are they using it a lot, are they coming back to it and asking for more? Or do they abandon it, and never use it at all? If you don’t have a way to measure their behaviour, there is no way for you to know whether you should invest your time in improving it or not.

The most effective way to measure user behaviour is to add some sort of analytics. Most of the basic analytics tracking is all you need in most cases, however, pretty much every analytics software allows you to go custom tracking, thereby shedding more light on what your audience loves or hates. One thing to remember here is that you should not track your users more than what is needed. Meaning, you should not track your user behaviour at the expense of their trust, which is more important to you and your business more than anything.

Crash Reporting

To give you a small introduction on this topic, a crash is a result of any issue (also called as a bug) that critically affects your app, and causes it to terminate without the consent of your user. That will be very annoying to your users, and there should be a system in place to let yourself alerted without the user having to send an email saying what is going on.

Fortunately, there are systems that are currently available in the market, such as Crashlytics which is very easy to set up inside your app. When something unexpected causes the app to exit (crash), it automatically uploads a trace of what was happening just before the crash. You can then pass it on to your developers, and since it comes with a stack trace, there are clues everywhere to reproduce the scenario and provide a fix in the next release.

App update checker

As part of constantly bringing new and improved features (and some bug fixes) to your audience, you should also let them know when a new version of the app is available in the app store (or play store). This could be a simple alert that shows up when the old version is launched, giving the user an option to go to the app store and download the latest version.

Specifying what’s new in the latest update will increase the likelihood of updating the app. This could be a part of the settings section of your app, or you can utilize the app store section dedicated to this. Explaining the advantages, such as a brand new feature that a user requested for, or fixing bugs that are annoying to the users, will also increase the chances of users getting excited and thereby updating the app.

Review Prompt

Here is the scenario. You put tons of effort into figuring out the features, the UI / UX, developed it, tested it thoroughly, launched it and now it is time to get feedback from the real testers (outside of you or your team of internal testers). Although analytics provides a glimpse of areas that are (or aren’t) popular in the app, there is a little magic in asking users to provide feedback directly to you.

That being said, what are the best ways to collect feedback? There are quite a few numbers of ways to do this effectively. The most and easiest would be to add a review prompt that is inbuilt in the platform you develop on. For example, in iOS, Apple provides a way to directly show an alert inside of the app, that sends ratings and reviews to the app store. If you want to take things a little further, you can add a link to a feedback form on your website, or just a textbox where the user can directly reach out to you through email.

One key thing to consider here is the placement of these feedback forms. I’d suggest asking for feedback when the user has done something critical in your app. For example, if your app stream content such as news or movies, ask them for content quality and user experience, after watching 3 videos or something similar of that nature. Since your user performed that key thing, you will have a better chance of receiving the most appropriate feedback based on what they had experienced a few seconds ago.

Reachability

Don’t get overwhelmed with this term, which is borrowed from Apple’s SDK documentation here. All it means is a mechanism to identify if your application is properly connected to a network, in most cases, the Internet. Most apps (apart from games) require some sort of connectivity with another system or internet to function properly. Lack of internet connection is easily mistaken with the bugs in the app. For example, you let your user send a message to another person from within the app, and if it is not connected to the internet, it fails. As you can imagine, you would not consider this as a bug. So, make it obvious. All it requires is a small message somewhere prominent on the screen, which tells your user that there is no connectivity at this time. Proper messaging vastly increase the user experience, and your audience will really appreciate it.

Conclusion

All of the above-mentioned traits should come at a minimum or no cost to the user. These are put in place to let your audience help you, and you should not do it at the expense of the user experience. For example, if you are adding an alert to let your user know that a new version is available, add a button so that they can update in one click. Do not let them figure out how to do it themselves. Make it easy.

The post Five Essential Components for MVP Mobile App appeared first on Now Playing Apps.

]]>
211
Taking advantage of free Github private repositories https://nowplayingapps.com/free-github-private-repositories/ Tue, 15 Jan 2019 02:32:18 +0000 https://nowplayingapps.com/?p=111 Github started to offer unlimited free private repositories to its users. Learn more about this new offering, and how to use it to your advantage.

The post Taking advantage of free Github private repositories appeared first on Now Playing Apps.

]]>
Developer’s favourite code sharing / source code management platform Github, recently announced unlimited private repositories for unpaid customers. This is really important, if you are working on a small project (maximum three collaborators) and don’t want to make it public on Github. Here is how you can take advantage of this new offer.

New private repository

If you have an existing repository which is currently public, jump directly to how to make your existing repository private. To start off, let us look how to start creating a new private repository. Log in to your Github account and click on the + icon on the top right of the navigation bar at the top and select New Repository.

Create a new repository in Github
Create a new repository in Github

Here is where you give information about your project. Fill it up and make sure to select “Private” option (Public is selected by default)

And that’s all to it. Enjoy your new private repository.

How to make your existing repository private

Follow these steps:

  1. Select the project you want to make private from the left side menu on your Github main page.
  2. From the menu that appears right below the repository name, select Settings with a gear icon logo
  3. Scroll down to the Danger Zone

First option would be to make your repository private. Click “Make private” button on the right side of that section.

Read all the warnings that appear in the model (this is very important!), and type the project name in the textbox below it and confirm.

Once your repository is private, a new private tag will appear next to your repository name.

Private tag is shown next to the repository name

That’s it. Your repository is now private!

What happens if you already have more than 3 collarborators

Unfortunately Github puts a limit of 3 team members to the free private repositories. If your project has more members than this limit, you will be presented with this message instead.

The account needs to be upgraded to Github Pro make it private.

What if I try to add more than 3 collaborators to a free private repository?

Github won’t let to add more than 3 members, and you’ll be presented with this message.

However, those 3 member limit is without counting yourself (as the owner of this repository). That means it will work for a 4 member team including the owner of the repository.

Summary

Github is one of the most (if not the most) popular code sharing platform, and this is a wonderful chance to safeguard your repo if you are a startup or a small project team trying to get your amazing idea of the ground. If your team if slightly bigger than what Github allows (at this time), you can also check out Bitbucket, which allows free private repositories up to 5 users.

If you have any questions or feedback, simply send it to me at sonny@nowplayingapps.com.

The post Taking advantage of free Github private repositories appeared first on Now Playing Apps.

]]>
111
How to renew the Apple Push Notification Service Certificate https://nowplayingapps.com/renewing-apple-push-notification-certificate/ Wed, 10 Oct 2018 03:00:39 +0000 https://nowplayingapps.com/?p=75 Explains how to renew your iOS app's APNs (Apple push notification service) certificate, without needing the help of a developer.

The post How to renew the Apple Push Notification Service Certificate appeared first on Now Playing Apps.

]]>
One fine morning you receive this email regarding your Apple push notification service certificate of your amazing app (or one that you are responsible for):

Your Apple Push Services Certificate will no longer be valid in 30 days. To generate a new certificate, sign in and visit Certificates, Identifiers & Profiles.

Certificate: Apple Push Services
Identifier: com.nowplayingapps.myawesomeapp
Team ID: 99X11XXXXX

To learn more about expired certificates, visit the certificates support page.


And your developer is not around. Of course, you have 30 more days, however, you don’t need access to your developer; you can do it yourself.

Check out our new upcoming service, RenewMyPush. With this, we hope to take the burden off you to update the push certificate manually. If this is something that you are interested in, let us know by visiting the service page, and we will let you know once this service is ready.

Apple push notification service (APNs) is the service created by Apple by which external applications (such as your backend or clients such as OneSignal or UrbanAirship) can send notifications to your customers. An APNS certificate establishes connectivity with your notification client and apple push notification service. Now, let’s dive in.

Prerequisite

You need a Mac computer and the apple developer account that has access to this app.

Let’s get started

Log in to the developer account, and from the left menu, select Certificates, IDs & Profiles link under the Overview section on the left side menu. From there select All from the Certificates section.

Locate the app id mentioned in the above email. Click on it to expand and verify the expiration date. It should match the one specified in the email. If you are not able to find the app id, then click [+] sign on the top right corner to create a new one. Skip the next step and jump directly to Create a new Push Certificate section.

Apple push notification service: Expiring APNS soon
Screenshot (1): Expiring APNS soon 

For push notification clients (such as OneSignal or UrbanAirship) to send push notifications on your behalf, it needs a certificate along with a private key. Let’s create one to replace the old certificate which is expiring soon. Just select App IDs link under Identifiers section on the left-hand side menu, and locate the app id (in this case com.nowplayingapps.myawsomeapp). Click on the app id to expand and scroll to the bottom of that section and click Edit

Optionally you can create a new certificate by clicking on the plus icon at the top of the Certificates page.

Scroll down to the Push Notifications section and click on Create Certificate from Production SSL Certificate section as seen in Screenshot (2) below.

Apple push notification service: Create New APNS certificate
Screenshot (2): Create New APNS certificate

Create a new Push Certificate

Select Apple Push Notification service SSL (Sandbox & Production) under Production title and click Continue.

Apple push notification service:  Select production push certificate
Screenshot (3): Select production push certificate

Select the app id from the list of App Ids specified in the drop-down, and click Continue.

Apple push notification service:  Select app id for which you want to renew APNS certificate
Screenshot (4): Select app id for which you want to renew APNS certificate

Upload your CSR (Certificate Signing Request). If you don’t have one, please google the steps to generate one. It’s really easy.

Click next, and eventually, you’ll get this message: Your certificate is ready. Click the Download button to download the certificate (.cer file) on to your mac.

Apple push notification service:  Download APNS Certificate
Screenshot (5): Download APNS Certificate

Saving Apple Push Notification Service (APNs) Certificate to your Mac’s keychain

Locate the downloaded certificate file, and double click on it to add it to your keychain.

Apple push notification service:  Install certificate to keychain
Screenshot (6): Install certificate to keychain

Open Keychain Access application on your mac, select Certificates menu on the left and search the app id on the search bar on the top right corner. You will see the app id option and make sure you have an option to expand it. Once you expand, you will see the private key as well.

Apple push notification service:  Find installed certificate in keychain
Screenshot (7): Find installed certificate in the keychain

 

Exporting Apple Push Notification Service (APNs) certificate to your push notification client

The last thing to do is to export this certificate (along with the private key) to your push notification client. This process is more or less the same for every client, I am explaining this for Onesignal.

Right-click on the certificate file and select Export Apple Push Certificate: <your-app-id>

if you don’t see this option, just click on the private key, and then right-click on the certificate file again.

Apple push notification service:  Export APNS and Private key to P12 file
Screenshot (8): Export APNS and Private key to a P12 file

Save it as a P12 file (you can leave the password field empty)

Login to your push notification client (OneSignal in this case). Locate your app and go to Settings

You will see that the expiration date exactly matches the one specified in the email above.

Apple push notification service:  Sign in to onesignal account and go to your app settings
Screenshot (9):  Sign in to onesignal account and go to your app settings

Just click edit and browse the P12 file you saved earlier.

That’s it, you have successfully renewed the certificate to link between OneSignal and Apple push notification service. You should now see a new expiration date, which is one year from now.

Final step – optional

Revoke the old Apple push notification service (APNs) certificate by going to the apple developer account, and finding the one that expires within 30 days.

Check out our new upcoming service, RenewMyPush. With this, we hope to take the burden off you to update the push certificate manually. If this is something that you are interested in, let us know by visiting the service page, and we will let you know once this service is ready.

If you have any questions or feedback, simply send it to me at sonny@nowplayingapps.com.

The post How to renew the Apple Push Notification Service Certificate appeared first on Now Playing Apps.

]]>
75
Getting unstuck with iOS developer certificates and profiles https://nowplayingapps.com/ios-developer-certificates-and-profiles/ Tue, 02 Oct 2018 19:51:59 +0000 https://nowplayingapps.com/?p=69 Flow chart that describes what steps to take to acquire all necessary iOS developer certificates and profiles from your apple developer account.

The post Getting unstuck with iOS developer certificates and profiles appeared first on Now Playing Apps.

]]>
Whether you are new to iOS development or you are a seasoned developer, the process of figuring out your iOS developer certificates and profiles can get intimidating. Things are worse if you have to take over an existing project from another developer. You can spend hours, if not days chasing the profiles and certificates and P12 files etc.

I have gone through this many times, and finally decided to create this flow chart. You start from the top (where it says Start), and simply follow along. 

Flowchart - step by step guide to understand iOS developer certificates and profiles

If you have any questions or feedback, simply send it to me at sonny@nowplayingapps.com.

Hope you enjoy and happy coding!

The post Getting unstuck with iOS developer certificates and profiles appeared first on Now Playing Apps.

]]>
69
How to get media duration from your iOS video player (AVPlayer) https://nowplayingapps.com/how-to-get-media-duration-from-your-ios-video-player-avplayer/ Fri, 28 Sep 2018 19:20:33 +0000 https://nowplayingapps.com/?p=60 Building a video player to stream content is absolutely amazing, however your customer experience is only as good as how accurate the information that is presented to them. I have had challenges putting accurate data in front of the user, and here is how overcame this challenge when using AVPlayer in iOS apps.

The post How to get media duration from your iOS video player (AVPlayer) appeared first on Now Playing Apps.

]]>
Building a video player to stream content is absolutely amazing, however, your customer experience is only as good as how accurate the information that is presented to them. I have had challenges putting accurate data in front of the user, and here is how I overcame this challenge when using AVPlayer in iOS apps.

The problem

If you are developing a custom video player skin, chances you have to somehow show the overall duration of the current playing media. And using AVPlayerItem’s duration is the best way of doing this. And this is how duration is accessed.

(lldb) po playerItem!.duration.seconds
nan

However, when done this way after we start playing, we get this “nan” 🙁

What the… NaN

The problem here is we are trying to access the duration before AVPlayer gets a chance to download the content (or manifest if using a streaming protocol like HLS). And the solution is to wait for the right time.

So, when’s the right time?

Simple answer. When the content is ready. Or otherwise when AVPlayerItem.Status.readyToPlay. Let’s see it in code

let streamURL = "http://184.72.239.149/vod/smil:BigBuckBunny.smil/playlist.m3u8"
playerItem = AVPlayerItem(url: URL(string: streamURL)!)
player = AVPlayer(playerItem: playerItem)
        
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.old, .new], context: nil)

and then observing like this:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    
    if keyPath == #keyPath(AVPlayerItem.status), let statusNumber = change?[.newKey] as? NSNumber {
        
        switch statusNumber.intValue {
        case AVPlayerItem.Status.readyToPlay.rawValue:
            let durationInSeconds = playerItem?.asset.duration.seconds ?? 0
            print("Ready to play. Duration (in seconds): \(durationInSeconds)")
        default: break
        }
    }
}

When you take this approach, make sure to remove the observer when you close the player or change playerItem inside the player

playerItem?.removeObserver(self, forKeyPath: #keyPath(AVPlayerItem.status))

It’s easier with Swift 4

With Swift 4, listening to changes like these are even easier. This is how:

observation = playerItem?.observe(\AVPlayerItem.status, changeHandler: { observedPlayerItem, change in
    if (observedPlayerItem.status == AVPlayerItem.Status.readyToPlay) {
        print("Current stream duration \(observedPlayerItem.duration.seconds)")
    }
})

It is easy to remove this observer, just assign it to nil. Here’s the link to the WWDC video

And that’s it! Happy streaming.

The post How to get media duration from your iOS video player (AVPlayer) appeared first on Now Playing Apps.

]]>
60
How to give more control to your users using MPNowPlayingInfoCenter https://nowplayingapps.com/how-to-give-more-control-to-your-users-using-mpnowplayinginfocenter/ Sat, 22 Sep 2018 18:28:58 +0000 https://nowplayingapps.com/?p=17 Building a video player to stream content is absolutely amazing, however your customer experience is only as good as how accurate the information that is presented to them. I have had challenges putting accurate data in front of the user, and here is how overcame this challenge when using AVPlayer in iOS apps.

The post How to give more control to your users using MPNowPlayingInfoCenter appeared first on Now Playing Apps.

]]>
Building an app that plays audio or video content? MPNowPlayingInfoCenter is a powerful API that Apple introduced (in iOS 5.0) that gives up to date information about your current playing content even if your app is backgrounded, or screen is locked. Let’s see what are the benefits of adding it to your app:

Benefits of adding NowPlayingInfo

  • Provide a quick overview of what your app is playing without opening your app
  • Includes all necessary metadata such as title, subtitle, start/end time, the artwork of current track and much more
  • Playback controls even if the app is in the background (such as play/pause, next/previous track)
  • Cast button to other airplay enabled devices
  • Visible on external devices (such as CarPlay) or other apple devices such as Apple TV or Apple Watch
  • Can be updated even if the app is running in the background

Let’s integrate

Alright, enough theory. Let’s dive in to see how your app can take advantage of this. MPNowPlayingInfoCenter has a singleton called NowPlayingInfo which is a dictionary where you can provide all this information (such as title, artist name, duration, artwork image etc.). That’s it! Easy as that. Let’s see it in code:

First things first. NowPlayingInfoCenter is part of MediaPlayer framework. So import it first like this:

import MediaPlayer

Alright, now lets us see what all properties are available to use.

var nowPlayingInfo = [String: Any]()
        
// prepare title and subtitle
nowPlayingInfo[MPMediaItemPropertyTitle] = "Movie Title"
nowPlayingInfo[MPMediaItemPropertyArtist] = "Artist Name"
        
// asynchronously download album art image.
// here, for simplicity, an image from asset catalog is loaded
if let albumArt = UIImage(named: "cover-art") {
    nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: albumArt.size, requestHandler: { imageSize in
        return albumArt
    })
}


If the current track is a live stream content (like news or a live event), you can take advantage of MPNowPlayingInfoPropertyIsLiveStream property.

// if playing item is a live stream. Default is false
nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true

To show current track duration and progress bar:

// Get asset duration from AVPlayerItem's AVAsset
// Duration is accurate only when AVPlayerItem.status == .readyToPlay.
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = playerItem.asset.duration.seconds
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = playerItem.currentTime().seconds


Please note that playerItem.asset.duration is accurate only once AVPlayer/AVAudioPlayer has loaded the stream URL and is ready to play. In order to do this, it is recommended to observe AVPlayerItem’s status property and checking whether it is AVPlayerItem.Status.readyToPlay. Refer to my blog post to read more about this.

And finally, assign our nowPlayingInfo dictionary to MPNowPlayingInfoCenter like this:

// final step is to assign our dictionary to 
// MPNowPlayingInfoCenter singleton
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo


One last thing. In order for the show the nowplayinginfo on the notification screen, you need to add this one last piece of code inside your AppDelegate’s didFinishLaunchingWithOptions function.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     application.beginReceivingRemoteControlEvents()
}

And there you go! Here is how it would look on an iPhone 7 Plus device:

and if your app supports Apple CarPlay, this is how it looks:

NowplayingInfo Carplay

Conclusion

This is a great feature to take advantage of for your iOS streaming app and gives control and accessibility to your users. Happy streaming!

Check out our new upcoming service, RenewMyPush. With this, we hope to take the burden off you to update the push certificate manually. If this is something that you are interested in, let us know by visiting the service page, and we will let you know once this service is ready.

The post How to give more control to your users using MPNowPlayingInfoCenter appeared first on Now Playing Apps.

]]>
17