Posted on Leave a comment

Support directional remotes in your tvOS app

A hand on a video game controller

In addition to the Siri Remote, tvOS provides support for a variety of hardware and software remotes with touch or button interfaces. When your app uses standard frameworks — like UIKit and AVKit — tvOS will automatically handle remote interactions to provide a consistent and familiar experience. If you have an app that includes custom interface elements or media players, you can still easily support navigation and content-based features for hardware and software remotes with both touch and button interfaces. Here’s how.

Explore app navigation

On Apple TV, people use a remote or game controller to navigate through interface elements like content posters, apps, or buttons, highlighting each item as they come to it. The highlighted item is said to be focused or in focus. The focus engine in UIKit controls focus and movement on tvOS, listens for incoming focus-movement events triggered from a remote or game controller, and notifies your app so you can provide the appropriate experience. All standard gestures in tvOS work with directional remotes by default, and you can also provide support in your app for custom gestures with classes like UITapGestureRecognizer.

About focus interactions for Apple TV

Adapt custom gestures for directional remotes
If you support custom gestures that control special actions within your app’s interface, you can add UITapGestureRecognizer to map to an explicit directional event.


let customGesture = UITapGestureRecognizer(target: self, action: #selector(specialAction))
customGesture.allowedPressTypes = [.downArrow]
view.addGestureRecognizer(customGesture)

UITapGestureRecognizer

Learn more about detecting gestures and button presses

Explore the App Programming Guide for tvOS

Support remotes with dedicated channel and guide buttons
Some Apple TV-compatible remotes offer dedicated guide buttons and up and down arrows to control channel changes and electronic programming guide paging functionality. If your app includes channels or a programming guide, you can support these interactions on remotes with dedicated buttons through the TV Services framework.

Providing Channel Navigation

Support playback interactions in a custom video player

If your app includes video content, you can use AVPlayerViewController to provide the best experience across all remote types. If you’ve created a custom video player, however, you can use UITapGestureRecognizer map specific remote buttons to playback interactions as well as MPRemoteCommandCenter to handle media player events.

MPRemoteCommandCenter

Becoming a Now Playable App

Remote Command Center Events

Play and pause
When someone plays content in your app, pressing select, play, pause or play/pause should update the playback state and display the player transport bar. You’ll need to use UITapGestureRecognizer and MPRemoteCommandCenter to handle these interactions in your custom player.


let playPauseGesture = UITapGestureRecognizer(target: self, action: #selector(togglePlaybackState)
playPauseGesture.allowedPressTypes = [.playPause, .select]
view.addGestureRecognizer(playPauseGesture) let remoteCommandCenter = MPRemoteCommandCenter.shared()
remoteCommandCenter.playCommand.addTarget(self, action: #selector(playHandler))
remoteCommandCenter.pauseCommand.addTarget(self, action: #selector(pauseHandler))

Skip forward and skip backward
When using a directional remote, people can skip through video in the appropriate direction by pressing left or right on the directional pad. Additionally, certain remotes have dedicated skip forward and skip backward buttons that can map to this functionality. To ensure someone can navigate forward and backward through your content, use UITapGestureRecognizer and MPRemoteCommandCenter to create the correct gestures.


let dPadLeftGesture = UITapGestureRecognizer(target: self, action: #selector(dPadLeftHandler))
dPadLeftGesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.leftArrow.rawValue)]
view.addGestureRecognizer(dPadLeftGesture) let dPadRightGesture = UITapGestureRecognizer(target: self, action: #selector(dPadRightHandler))
dPadRightGesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.rightArrow.rawValue)]
view.addGestureRecognizer(dPadRightGesture) let remoteCommandCenter = MPRemoteCommandCenter.shared()
remoteCommandCenter.skipForwardCommand.addTarget(self, action: #selector(skipForwardHandler))
remoteCommandCenter.skipBackwardCommand.addTarget(self, action: #selector(skipBackwardHandler))

Fast forward and rewind
People can fast forward and rewind through content in different ways depending on the remote they use. Some remotes offer dedicated fast forward and rewind buttons, while others achieve this with a long press on the left or right directional pad buttons.


Note: On tvOS, we recommend using the following UI labels to pair with the corresponding supported player rates.

UI Labels to tvOS Playback Rates
1x = 8.0
2x = 24.0
3x = 48.0
4x = 96.0


Dedicated fast forward and rewind buttons
For remotes with dedicated fast forward and rewind buttons, a short press will initiate a continuous seek forward or backward. Each subsequent press of that button will increase the seek rate. Once someone passes the last seek rate, the player returns to its normal playback rate. If the opposite button is pressed while seeking, it decreases the seek rate; each subsequent press will do the same until the player returns to its normal playback rate.

You can support these controls in your app with changePlaybackRateCommand in MPRemoteCommandCenter. You’ll also want to make sure to update your player rate with the playbackRate property of the MPChangePlaybackRateCommandEvent.

If someone holds a dedicated fast forward or rewind button, MPRemoteCommandCenter will fire a seekForwardCommand or seekBackwardCommand. Your registered target will receive MPSeekCommandEventType.beginSeeking, and your app should set the player to the desired seek rate. Once someone releases the button, your app receives a new command event with the case MPSeekCommandEventType.endSeeking, telling it to return the player rate to normal.

Directional pad fast forward and rewind
If a person long presses the left or right directional pad buttons, your app should seek forward or backward respectively and update the seek rate. While seeking, a person can use a short press on the left or right directional pad buttons to update the seek rate as described in the previous section.

Adopt fast forward and rewind in your custom video player
To incorporate these gestures in your app for all remotes, you’ll want to use MPRemoteCommandCenter, UITapGestureRecognizer and UILongPressGestureRecognizer.

// MPRemoteCommands to handle dedicated fast forward and rewind buttons
let remoteCommandCenter = MPRemoteCommandCenter.shared() // MPRemoteCommands to handle dedicated fast forward and rewind (short presses)
remoteCommandCenter.changePlaybackRateCommand.addTarget { [unowned self] event in guard let event = event as? MPChangePlaybackRateCommandEvent else { return .commandFailed } self.assetPlayer.player.rate = event.playbackRate return .success
} // MPRemoteCommands to handle dedicated fast forward button (long press)
remoteCommandCenter.seekForwardCommand.addTarget { [unowned self] event in guard let event = event as? MPSeekCommandEvent else { return .commandFailed } if event.type == .beginSeeking { self.assetPlayer.player.rate = 24.0 } if event.type == .endSeeking { self.assetPlayer.player.rate = 1.0 } return .success
} // MPRemoteCommands to handle dedicated rewind button (long press)
remoteCommandCenter.seekBackwardCommand.addTarget { [unowned self] event in guard let event = event as? MPSeekCommandEvent else { return .commandFailed } if event.type == .beginSeeking { self.assetPlayer.player.rate = -24.0 } if event.type == .endSeeking { self.assetPlayer.player.rate = 1.0 } return .success
} // Gestures to handle fast forward and rewind from directional pad // Gesture to handle dpad right (long press)
let dPadRightLong = UILongPressGestureRecognizer(target: self, action: #selector(dPadRightLongHandler))
dPadRightLong.allowedPressTypes = [NSNumber(value: UIPress.PressType.rightArrow.rawValue)]
view.addGestureRecognizer(dPadRightLong) // Gesture to handle dpad left (long press)
let dPadLeftLong = UILongPressGestureRecognizer(target: self, action: #selector(dPadLeftLongHandler))
dPadLeftLong.allowedPressTypes = [NSNumber(value: UIPress.PressType.leftArrow.rawValue)]
view.addGestureRecognizer(dPadLeftLong) // Gesture to handle dpad right (short press)
let dPadRightGesture = UITapGestureRecognizer(target: self, action: #selector(dPadRightHandler))
dPadRightGesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.rightArrow.rawValue)]
view.addGestureRecognizer(dPadRightGesture) // Gesture to handle dpad left (short press)
let dPadLeftGesture = UITapGestureRecognizer(target: self, action: #selector(dPadLeftHandler))
dPadLeftGesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.leftArrow.rawValue)]
view.addGestureRecognizer(dPadLeftGesture)

Support additional interactions in a custom player

People expect up or down swipes or presses to provide a consistent experience during video playback, like showing the player controls and transport bar on a press or swipe up, or showing the information panel on a swipe or press down.

Transport Bar
People should be able to see how much time remains on a piece of content. Swiping up or pressing up on a directional pad should show the player’s transport bar without stopping or pausing the player.


let upGesture = UITapGestureRecognizer(target: self, action: .upGestureRecognizer)
upGesture.allowedPressTypes = [.upArrow]
view.addGestureRecognizer(upGesture)

Information Panel
People should be able to access subtitle and audio selections along with other options while viewing content. Swiping down or pressing down on a directional pad should show these options without stopping or pausing the player.


let downGesture = UITapGestureRecognizer(target: self, action: .downGestureRecognizer)
downGesture.allowedPressTypes = [.downArrow]
view.addGestureRecognizer(downGesture)

Putting Your Users In Control
No matter which interaction method someone chooses to use with Apple TV, you can ensure they remain in control by offering a great experience in your app for all remotes. It’s easy when you use system frameworks like AVFoundation and AVKit and support custom gestures and media interactions with UITapGestureRecognizer and MPRemoteCommandCenter. And when you do, it lets people enjoy your content without worrying how to interact with your app.

Posted on Leave a comment

Apple Search Ads introduces a new way to promote apps

Two side-by-side iPhones display ads on the Search tab. One shows an ad before a search term is entered and the other shows an ad in search results.

Apple Search Ads has always made it easy to promote your apps at the top of relevant search results on the App Store. Now you can reach users even before they search with an ad placement on the Search tab. It’s a simple and effective way to help users discover your apps. Try Apple Search Ads for free with a 100 USD credit.

Learn more about Apple Search Ads

Posted on Leave a comment

Search suggestions now on the App Store

The App Store provides a safe and trusted place for users around the world to discover and download your apps. And now with search suggestions, it provides another great discovery method. When users search on the App Store, they see suggested search terms related to what they’re looking for. Tapping a suggestion adjusts their search, so they’ll easily find even more apps that might fit their needs. App Store search is one of the main ways that users discover apps, and developers are already seeing more downloads from those who use these suggestions.

Search suggestions are currently available in Australia, Canada, the United Kingdom, and the United States. Additional regions will be made available over time.

Learn best practices for App Store search optimization

Posted on Leave a comment

What’s new in advertising attribution technologies

Private Click Measurement is now available in iOS 14.5 and iPadOS 14.5, allowing advertising networks to measure the effectiveness of advertisement clicks within apps and websites that navigate to a website. This information can be used to understand which advertisements drive conversions (such as purchases or signups) — while maintaining user privacy.

Starting with the beta release of iOS 14.6 and iPadOS 14.6, advertising networks that use SKAdNetwork 3.0 are eligible to receive attribution postbacks if their advertisement does not win the attribution. This allows up to five advertising networks to see when an advertisement they ran was a runner-up to an app installation.

Learn more about SKAdNetwork

Posted on Leave a comment

Online group event in-app purchase requirement update

Last year, to support apps that adapted services from in-person to digital due to the COVID-19 pandemic, we temporarily deferred the requirement to offer paid online group event services (one-to-few and one-to-many realtime services) through in-app purchase in accordance with App Store Review Guideline 3.1.1. As the world continues to recover from the pandemic, we’d like to support the communities that are still providing digital services in place of in-person group events by extending the deadline further to December 31, 2021.

As a reminder, guideline 3.1.3(d) allows apps offering realtime person-to-person services between two individuals (for example, tutoring students, medical consultations, real estate tours, or fitness training) to use purchase methods other than in-app purchase.

Posted on Leave a comment

App Store submission update

Make sure your apps make the most of iOS 14, iPadOS 14, and watchOS 7. Build your apps with the Xcode 12.5 Release Candidate, update your product pages, and submit them for review.

iPhone and iPad apps. Starting April 26, 2021, all iPhone and iPad apps submitted to the App Store must be built with Xcode 12 and the iOS 14 SDK or later. The iOS SDK provides access to exciting new features like App Clips, Home screen widgets, ARKit, RealityKit, and much more.

Learn more

Apple Watch apps. Starting April 26, 2021, all watchOS apps submitted to the App Store must be built with Xcode 12 and the watchOS 7 SDK or later. The watchOS 7 SDK lets you create multiple complications for each complication family using new ClockKit APIs, SwiftUI Complications, and Xcode Previews — so users can enjoy your app right on their watch face.

Learn more

Posted on Leave a comment

Upcoming AppTrackingTransparency requirements

With the upcoming public release of iOS 14.5, iPadOS 14.5, and tvOS 14.5, all apps must use the AppTrackingTransparency framework to request the user’s permission to track them or to access their device’s advertising identifier. Unless you receive permission from the user to enable tracking, the device’s advertising identifier value will be all zeros and you may not track them.

When submitting your app for review, any other form of tracking — for example, by name or email address — must be declared in the product page’s App Store Privacy Information section and be performed only if permission is granted through AppTrackingTransparency. You’ll also need to include a purpose string in the system prompt to explain why you’d like to track the user, per App Store Review Guideline 5.1.2(i). These requirements apply to all apps starting April 26, 2021.

As a reminder, collecting device and usage data with the intent of deriving a unique representation of a user, or fingerprinting, continues to be a violation of the Apple Developer Program License Agreement.

Learn more about user privacy and data use

Posted on Leave a comment

Program enrollment available in more regions in the Apple Developer app

It’s now simpler than ever for developers around the world to enroll in the Apple Developer Program. As of today, the Apple Developer app also supports enrollment in Canada, France, India, Italy, Netherlands, Russia, and Spain.

Developers can start and finish their membership purchase with local payment methods on iPhone or iPad. And since membership is provided as an auto-renewable subscription, keeping it active is easy.

View on the App Store

Posted on Leave a comment

Get ready for AppTrackingTransparency

Make sure your apps are ready for iOS 14.5, iPadOS 14.5, and tvOS 14.5. With the upcoming public release, all apps must use the AppTrackingTransparency framework to request the user’s permission to track them or to access their device’s advertising identifier. Unless you receive permission from the user to enable tracking, the device’s advertising identifier value will be all zeros and you may not track them.

When submitting your app for review, any other form of tracking — for example, by name or email address — must be declared in the product page’s App Store Privacy Information section and be performed only if permission is granted through AppTrackingTransparency. You’ll also need to include a purpose string in the system prompt to explain why you’d like to track the user, per App Store Review Guideline 5.1.2(i). These requirements apply to all apps starting with the public release of iOS 14.5, iPadOS 14.5, and tvOS 14.5.

As a reminder, collecting device and usage data with the intent of deriving a unique representation of a user, or fingerprinting, continues to be a violation of the Apple Developer Program License Agreement.

Learn more about user privacy and data use

Posted on Leave a comment

Announcing WWDC21

The Apple Worldwide Developers Conference is coming to a screen near you, June 7 to 11. Join the worldwide developer community for an all-online program with exciting announcements, sessions, and labs at no cost. You’ll get a first look at the latest Apple platforms, tools, and technologies — so you can create your most innovative apps and games yet. Stay tuned for additional details.

Now through April 18, we invite students who love to code to submit their Swift playground to this year’s Swift Student Challenge. Winners will receive exclusive WWDC21 outerwear and a customized pin set.

Learn about the Challenge