AT&T U-verse® Enabled App

AT&T U-verse® Enabled
How to Write Your First AT&T U -verse Enabled iOS ® App
Publication Date: November 1st, 2013
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Legal Disclaimer
This document and the information contained herein (collectively, the "Information") is provided to you (both the individual receiving
this document and any legal entity on behalf of which such individual is acting) ("You" and "Your") by AT&T, on behalf of itself and
its affiliates ("AT&T") for informational purposes only. AT&T is providing the Information to You because AT&T believes the
Information may be useful to You. The Information is provided to You solely on the basis that You will be responsible for making
Your own assessments of the Information and are advised to verify all representations, statements and information before using or
relying upon any of the Information. Although AT&T has exercised reasonable care in providing the Information to You, AT&T does
not warrant the accuracy of the Information and is not responsible for any damages arising from Your use of or reliance upon the
Information. You further understand and agree that AT&T in no way represents, and You in no way rely on a belief, that AT&T is
providing the Information in accordance with any standard or service (routine, customary or otherwise) related to the consulting,
services, hardware or software industries.
AT&T DOES NOT WARRANT THAT THE INFORMATION IS ERROR-FREE. AT&T IS PROVIDING THE INFORMATION TO YOU
"AS IS" AND "WITH ALL FAULTS." AT&T DOES NOT WARRANT, BY VIRTUE OF THIS DOCUMENT, OR BY ANY COURSE OF
PERFORMANCE, COURSE OF DEALING, USAGE OF TRADE OR ANY COLLATERAL DOCUMENT HEREUNDER OR
OTHERWISE, AND HEREBY EXPRESSLY DISCLAIMS, ANY REPRESENTATION OR WARRANTY OF ANY KIND WITH
RESPECT TO THE INFORMATION, INCLUDING, WITHOUT LIMITATION, ANY REPRESENTATION OR WARRANTY OF
DESIGN, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, OR
ANY REPRESENTATION OR WARRANTY THAT THE INFORMATION IS APPLICABLE TO OR INTEROPERABLE WITH ANY
SYSTEM, DATA, HARDWARE OR SOFTWARE OF ANY KIND. AT&T DISCLAIMS AND IN NO EVENT SHALL BE LIABLE FOR
ANY LOSSES OR DAMAGES OF ANY KIND, WHETHER DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE,
SPECIAL OR EXEMPLARY, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
INTERRUPTION, LOSS OF BUSINESS INFORMATION, LOSS OF GOODWILL, COVER, TORTIOUS CONDUCT OR OTHER
PECUNIARY LOSS, ARISING OUT OF OR IN ANY WAY RELATED TO THE PROVISION, NON-PROVISION, USE OR NON-USE
OF THE INFORMATION, EVEN IF AT&T HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES OR DAMAGES.
IOS is a trademark or registered trademark of Cisco in the U.S. and other countries.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
i
Table of Contents
Contents
1
Introduction .......................................................................................................................................... 1
2
Overview ............................................................................................................................................... 2
3
Initial Setup ........................................................................................................................................... 4
4
RemoteControlViewController Design.................................................................................................. 5
5
4.1
Implementing the viewDidLoad Method ...................................................................................... 5
4.2
Implementing the UverseConnectedManagerDidChangeState Notification Callback Method ... 7
4.3
Implementing the connectToReceiver Method ............................................................................ 9
4.4
About the UverseConnectedManagerErrorOccurred Notification Callback Method ................. 10
4.5
Handling the RemoteKey and Button Commands on the RemoteControlViewController......... 10
SetTopBoxPickerTableViewController Design .................................................................................... 13
5.1
Implementing the viewDidLoad Method .................................................................................... 14
5.2
Implementing the registerForNotifications Method .................................................................. 14
5.3
Implementing the uveSetTopBoxEnagagementDidSucceed notification Callback Method ....... 15
5.4
Implementing the uveSetTopBoxEnagagementDidFail notification Callback Method............... 15
5.5
Implementing the UverseConnectedManagerSetTopBoxesUpdated Notification Callback
Method ................................................................................................................................................... 17
6
5.6
Implementing the setupListOfstb Method ................................................................................. 17
5.7
Implementing the UITableView:cellForRowAtIndexPath Method ............................................. 18
5.8
Implementing the didSelectRowAtIndexPath Method ............................................................... 20
5.9
Implementing the PasswordViewController Delegate Method ................................................. 21
PasswordViewController Design ......................................................................................................... 22
6.1
Implementing the viewDidLoad Method .................................................................................... 22
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
ii
Table of Figures
Figure 4-1: RemoteControlViewController Screen ....................................................................................... 5
Figure 5-1: SetTopBoxPickerTableViewController ...................................................................................... 13
Figure 6-1: PasswordViewController .......................................................................................................... 22
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
iii
Table of Examples
Example 4-1: viewDidLoad method. ............................................................................................................. 7
Example 4-2: UverseConnectedManagerDidChangeState ........................................................................... 8
Example 4-3: associateToSTBAfterDiscovery Method .................................................................................. 9
Example 4-4: connectToReceiver................................................................................................................ 10
Example 4-5: stbCommandbuttonPressed ................................................................................................. 11
Example 4-6: commandSucceeded ............................................................................................................. 12
Example 5-1: viewDidLoad .......................................................................................................................... 14
Example 5-2: registerForNotifications ........................................................................................................ 15
Example 5-3: uveSetTopBoxEnagagementDidSucceed .............................................................................. 15
Example 5-4: uveSetTopBoxEnagagementDidFail notification................................................................... 17
Example 5-5: UverseConnectedManagerSetTopBoxesUpdated ................................................................ 17
Example 5-6: setupListOfstb ....................................................................................................................... 18
Example 5-7: UITableView:cellForRowAtIndexPath ................................................................................... 20
Example 5-8: didSelectRowAtIndexPath ..................................................................................................... 21
Example 5-9: PasswordViewController....................................................................................................... 21
Example 6-1: viewDidLoad .......................................................................................................................... 23
Example 6-2: passwordEntered .................................................................................................................. 23
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
iv
1 Introduction
This document takes you through the creation of the elements that must be
included in a functional U-verse Enabled app. These elements include a
discovery and authentication process like the one described in the AT&T U-verse
® Enabled User Device Design Guidelines which establishes the connection
between your app and the U-verse receiver (SetTopBox), and a basic remote
control that allows your app to invoke receiver commands. The code that is
shown and discussed in this document is downloaded from the sample code
page.
The main body of the sample app described in this document primarily focuses
on the authentication process. This portion of the sample app has been designed
to be as reusable as possible.
Some of the terminology that is used in the U-verse API, and in this document, is
different from the terms on the U-verse receiver. These are the terms that a user
will be familiar with, and you should not use the name used in the API in any user
facing areas. The main differences are:

The U-verse receiver is referred to as the SetTopBox in the API.

Default mode is referred to as "Open" mode for the receiver engagement in
the API.

Custom mode is referred to as "Managed" mode for the receiver engagement
in the API.
To complete this tutorial and create your first U-verse Enabled iOS app, it is
assumed that you have completed the following prerequisites:

You have completed your app registration and have been issued an AAP for
test purposes. The process for completing both of these tasks is described in
the document How to Register and Start Developing AT&T U-verse Enabled
Applications.

You have set up your project as described in the document How to Set Up an
AT&T U-verse-Enabled Project in Xcode®.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 1 of 25
2 Overview
To implement the discovery, authentication, and remote control elements that are
essential to a functional U-verse Enabled app, the project described in this
tutorial uses these three objects in the U-verse Enabled SDK:

The SetTopBox object contains state information, such as the current
program that the user is watching. The object also contains methods for
sending commands to the SetTopBox, querying for information about the
current program or the user’s recording status, and for engaging with the
SetTopBox.

UverseConnectedManager Is a singleton object that is created by calling
[UverseConnectedManager sharedManager], and it is kept alive for the lifetime
of the app. This object is used to communicate between the U-verse Network
Service and your application. The UverseConnectedManager object handles
discovery of the SetTopBoxes on the network and has a number of helpful
properties such as SetTopBoxes which returns an NSArray of SetTopBoxes
on the current network after discovery has completed. The
mostRecentlyEngagedSetTopBox property provides a reference to the
SetTopBox that was most recently engaged by the user. There are two
common uses for this property:

o
The app can check the value after discovery is complete and, if not nil,
choose to engage with this SetTopBox automatically for the user.
o
The app can check this value to determine which SetTopBox was most
recently engaged, as the UverseConnectedManager will keep this value
up to date as the user engages with SetTopBoxes in a multi SetTopBox
environment.
The uveRemoteButtonCommand object is used to send RemoteKey
commands to the SetTopBox. These commands are used to emulate buttons
on the remote control (like channel up), or to send alphanumeric characters.
To allow the user to interact with the functionality of these objects, the UI for this
sample app uses these four different View Controllers:

The RemoteControlViewController is used to create the main screen. This
view controller is the root view controller for the app. It displays a simple
remote controller using Apple’s® default buttons to demonstrate the
functionality of the uveRemoteKeyCommand, and to handle the discovery of
the SetTopBoxes.

The SetTopBoxPickerTableViewController handles the selection and
engagement of a SetTopBox on the U-verse Network. This is either done
automatically, in the discovery phase, or as a user event, if the user wishes to
change the setTopBox that they are engaged with.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 2 of 25

The LinkingInfoViewController is the simplest view controller in the project. Its
role is to provide helpful information to the user about the steps needed to
engage a SetTopBox with a U-verse Enabled application. The details of how
to implement this view controller will not be explained in this tutorial, but the
implementation is included in the accompanying sample code.

The PasswordViewController is used to prompt the user for a PIN. The
controller then passes the entered password to its delegate for verification.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 3 of 25
3 Initial Setup
There are a few design choices you can make when creating a U-verse Enabled
app. In this sample app, the AppDelegate selects whether the app is to be run in
a test environment or the production environment and selects the correct AAP
files and the url of the server for the environment. Most of the other interaction
with the library is handled in the RemoteControlViewController.
It is important to note that your app will be able to engage with a U-verse receiver
until you have correctly setup the AAP in your app for the environment you are
working in. The details of how to do this are covered in the document How to
Setup an AT&T U-verse Enabled Project in Xcode, so they will not be repeated in
this tutorial.
The following sections of this tutorial describe in detail the implementation of the
four view controllers.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 4 of 25
4 RemoteControlViewController Design
The RemoteControlViewController is the root view controller and it is used to
create the main screen of the app shown in the following figure.
Note: The following View is designed to be replaced by a View in your own app,
and as such, it is very basic. It’s not recommended that you present a similar
design to users.
Figure 4-1: RemoteControlViewController Screen
4.1 Implementing the viewDidLoad Method
The code to implement the RemoteControlViewController begins with the
viewDidLoad method which performs the following actions:

Retrieving a reference to the sharedManager from the
UverseConnectedManager object.

Registering for the uveSetTopBoxCommandDidSucceed,
uveSetTopBoxCommandDidFail,
UverseConnectedManagerDidChangeState, and
UverseConnectedManagerErrorOccurred notifications.
This is the minimum set of notifications that you need to register in order to
create a functional U-verse app. The
UverseConnectedManagerDidChangeState notification is used for the
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 5 of 25
changes in discovery state, but it can also inform you of any state changes
that occur after discovery. For example, it will notify you if the app loses the
network connection to the SetTopBox.

Checking the state of the UverseConnectedManager (using the reference
uvcMgr in the code example).
If the state is LibraryNotReady, you can use the startDiscovery method of the
UverseConnectedManger to start discovery.

Checking whether the discovery state is not LibraryReady. While this
condition is similar to the last check, the subtle difference is that it is checking
whether the state is LibraryNotReady, or DiscoveringNetwork. These are the
states that the app can be in before it is ready to use. If it is in one of these
states, the application displays an alert to the user indicating that the app is
performing discovery.

The final portion of the viewDidLoad method sets the title in the navigation
bar and a button for the user to reconnect with a U-verse receiver.
The following code shows the implementation of the viewDidLoad method.
viewDidLoad Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| - (void)viewDidLoad
| {
|
[super viewDidLoad];
|
UverseConnectedManager *uvcMgr = [UverseConnectedManager
sharedManager];
|
[self registerForNotifications];
|
if(uvcMgr.state == LibraryNotReady){
|
[uvcMgr startDiscovery];
|
}
|
if (uvcMgr.state != LibraryReady){
|
ProgressIndictator *waitView = [[ProgressIndictator alloc]
initWithTitleLabelText:@"Please Wait"
andInfoLabelText:@"Discovering Network"];
|
self.spinnerView = waitView;
|
[self.view addSubview:waitView];
|
}
|
if (uvcMgr.mostRecentlyEngagedSetTopBox == nil){
|
self.title = @"No Receiver";
|
[self connectToReceiver];
|
}
|
|
UIBarButtonItem *connectButton = [[UIBarButtonItem alloc]
initWithTitle:@"Connect" style:UIBarButtonItemStyleBordered
target:self action:@selector(connectToReceiver)];
|
self.navigationItem.rightBarButtonItem = connectButton;
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 6 of 25
21
22
23
24
|
|
UIBarButtonItem *sdkButton = [[UIBarButtonItem alloc]
initWithTitle:@"SDK 2.0" style:UIBarButtonItemStyleBordered
target:self action:@selector(uverse2sdkfeatures)];
|
self.navigationItem.leftBarButtonItem = sdkButton;
| }
Example 4-1: viewDidLoad Method
4.2 Implementing the UverseConnectedManagerDidChangeState
Notification Callback Method
The next method for implementing the RemoteControlViewController is the
callback for the UverseConnectedManagerDidChangeState notification.
The three possible states that the UverseConnectManager can be in are

LibraryNotReady: This is the initial state of the library. When the app starts,
the library will be in the LibraryNotReady state. The library can be returned to
LibraryNotReady after discovery if there is an error in Discovery. You can
listen for the notification UverseConnectedManagerErrorOccurred to be
notified of any errors that occur.

DiscoveringNetwork: This is a transient state while the Library performs
discovery. Discovery will search for the U-verse receivers on the same local
WiFi network as the iOS Device.

LibraryReady: The LibraryReady state indicates you are able to interact with
the library. All the setup has completed and the next step is to engage with a
U-verse receiver. After you engage with a U-verse receiver, you will then be
able to interact with that U-verse receiver.
The important case here is the LibraryReady state, in which the application code
removes the alert from the screen and then calls the
associateToSTBAfterDiscovery method.
UverseConnectedManagerDidChangeState
1
2
3
4
5
6
7
8
| -(void)uveMgrDidChangeState:(NSNotification *)notification{
|
|
UverseConnectedManager *uvcMgr = [UverseConnectedManager
sharedManager];
|
|
switch(uvcMgr.state) {
|
case LibraryReady:{
|
NSLog(@"NOTIFICATION
UverseConnectedManagerDidChangeState: LibraryReady");
|
[self.spinnerView removeFromSuperview];
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 7 of 25
9
10
11
12
13
14
15
16
17
18
|
|
|
|
|
|
|
|
|
|
19
20
21
22
|
|
|
|
23
24
25
26
27
28
|
|
|
|
|
self.spinnerView = nil;
[self associateToSTBAfterDiscovery];
break;
}
case LibraryNotReady:{
[self.spinnerView removeFromSuperview];
self.spinnerView = nil;
NSLog(@"NOTIFICATION
UverseConnectedManagerDidChangeState: LibraryNotReady");
break;
}
case DiscoveringNetwork:{
NSLog(@"NOTIFICATION
UverseConnectedManagerDidChangeState: DiscoveringNetwork");
UILabel *infoLabel = self.spinnerView.infoLabel;
infoLabel.text = @"Discovering Network";
break;
}
}
}
Example 4-2: UverseConnectedManagerDidChangeState
The associateToSTBAfterDiscovery method is where the majority of the work will
be done after discovery. The method performs the following actions:

Checking whether the mostRecentlyEngagedSetTopBox property of the
UverseConnectedManager singleton is set. If this property is not nil, the
receiver is the one that the user most recently engaged with.

Determining the connection mode of the receiver. The connection mode
determines how the application can engage with the receiver.
o
The user can immediately engage with a receiver if the receiver is in
Default mode OR in Custom mode and the user has previously
entered the four digit passcode for this application and device. This
would be the most common use case in a household that has only
one receiver. When the app launches and goes through the discovery
process, the user does not need to select the receiver that they wish
to interact with. This can be done by either calling the engage method
on a SetTopBox or by calling the
associatedAndEngageWithOneTimeToken with an argument of nil.
o
If the receiver is in the Custom (Managed) mode and this is the first
time that the user is using this U-verse Enabled app on the device, a
four digit passcode will need to be entered by the user. For details,
see the AT&T U-verse ® Enabled User Device Design Guidelines.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 8 of 25
The following code shows the implementation of the
associateToSTBAfterDiscovery method.
associateToSTBAfterDiscovery Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| -(void)associateToSTBAfterDiscovery{
|
UverseConnectedManager *uvcMgr = [UverseConnectedManager
sharedManager];
|
SetTopBox *lastUsedSTB = uvcMgr.mostRecentlyEngagedSetTopBox;
|
if (lastUsedSTB != nil){
|
if (lastUsedSTB.mode == UverseModeOpen ||
(lastUsedSTB.mode == UverseModeManaged &&
lastUsedSTB.isAssociated)){
|
[lastUsedSTB associateAndEngageWithOneTimeToken:nil];
|
self.title =
uvcMgr.mostRecentlyEngagedSetTopBox.friendlyName;
|
}else {
|
[self connectToReceiver];
|
}
|
} else {
|
[self connectToReceiver];
|
}
| }
Example 4-3: associateToSTBAfterDiscovery Method
4.3 Implementing the connectToReceiver Method
The following code example shows the connectToReceiver method, where a
View Controller (the SettopBoxPickerTableViewController) is launched so the
user can select the SetTopBox that they wish to connect to, and if necessary,
launch the passcode entry screen. The View Controller is embedded in a
UINavigationController for easier management of the UINavigationBar and so
that it can be presented modally.
connectToReceiver
1
2
3
4
5
6
| -(IBAction)connectToReceiver{
|
UverseConnectedManager *uvcMgr = [UverseConnectedManager
sharedManager];
|
if (uvcMgr.state == LibraryReady && uvcMgr.SetTopBoxes !=
nil){
|
SettopBoxPickerTableViewController *pickerController =
[[SettopBoxPickerTableViewController alloc]
initWithStyle:UITableViewStyleGrouped];
|
UINavigationController *navController =
[[UINavigationController alloc]
initWithRootViewController:pickerController];
|
[self presentModalViewController:navController
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 9 of 25
7
8
9
10
11
12
13
14
animated:YES];
|
[navController release];
|
[pickerController release];
|
} else if (uvcMgr.state == LibraryNotReady) {
|
[uvcMgr startDiscovery];
|
} else {
|
// if the middle of Discovery
|
}
| }
Example 4-4: connectToReceiver
4.4 About the UverseConnectedManagerErrorOccurred
Notification Callback Method
The callback method that handles the UverseConnectedManagerErrorOccurred
notification covers any errors that may occur while the app is running. When you
are first creating a U-verse Enabled project, the most common errors that you will
receive are:

uveInternalError(3000) - This normally occurs if there is a problem with the
AAP bundle that you used, e.g., you are using the wrong AAP for the
environment.

uveNetworkError(3001) - This error occurs when your app has a problem
communicating with the server. The most common cause of this error is a
network error; it can also occur if you set the server to the wrong URL.

uveApplicationBlocked(3002) - This occurs when either the app bundle
identifier or the build number of the app have not been registered with AT&T.
The code for this callback method is not described here, but the implementation
is in the sample code of the project.
4.5 Handling the RemoteKey and Button Commands on the
RemoteControlViewController
The view of the RemoteControlViewController (shown in figure 1) displays a
navigation bar with a bar button (labeled “Connect”) on the right, to start the
authentication process. The remainder of the view controller contains the remote
control buttons.
The view controller is split into two sections, the top section, which contains the
basic buttons necessary for navigation through any U-verse app and through the
menu system on the SetTopBox, and the lower section which contains a number
pad and a few extra buttons.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 10 of 25
Each of the RemoteKeys is exposed by the SDK in an enum contained in the file
RemoteKey.h. The easiest way to send a command to the SetTopBox is to set
the tag property of a button to the value of that button in the RemoteKey.h file.
For example, the up button on the directional pad has the value of 24. By passing
RemoteKey values to an action method, the same action method can be reused
for each RemoteKey. The stbCommandbuttonPressed method, shown in the
following code snippet, uses this technique.
The method performs these actions:

Casting the sender to a UIButton so that the compiler will not give a warning
when the tag property of the object is accessed.

Creating the command object which is of type uveRemoteButtonCommand.
This is the object that is used anytime you are sending a remote Control
Button to the receiver, i.e., any of the Remote keys declared in
RemoteKey.h file.

Sending the command to the receiver and releasing the command.
stbCommandbuttonPressed
1
2
3
4
5
7
| - (IBAction)stbCommandbuttonPressed:(id)sender{
|
UIButton *button = (UIButton *)sender;
|
uveRemoteButtonCommand *buttonCommand
=[[uveRemoteButtonCommand alloc] initWithRemoteKey:button.tag];
|
|
[[[UverseConnectedManager sharedManager]
mostRecentlyEngagedSetTopBox] sendSetTopBoxCommand:buttonCommand];
| }
Example 4-5: stbCommandbuttonPressed
As the command object will not contain any information that will be returned, it is
safe to release the object after it has been sent. However, this is different for
some of the other commands that inherit from uveBaseCommand. For example,
the uveRecordingsCommand includes the array of recordings as a property
called recordings on the uveRecordingCommand, so you must retain a
reference to the command so that you can access the recordings property in the
callback to the uveSetTopBoxCommandDidSucceed notification.
All commands that are sent to the receiver are asynchronous, so you will need to
listen for the uveSetTopBoxCommandDidSucceed and
uveSetTopBoxCommandDidFail notifications to determine the success or failure
of the command. As all commands that inherit from uveBaseCommand will send
the same notification, the first step is to find out what type of command has sent
the notification. This can be queried from the uveSetTopBoxCommandKey key
that is passed as a parameter in the notification object.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 11 of 25
The following code shows the commandSucceeded method which is the callback
for the uveSetTopBoxCommandDidSucceed notification.
commandSucceeded
1
2
3
4
5
6
7
8
| -(void)commandSucceeded:(NSNotification *)notification {
|
uveBaseCommand *baseCommand = (uveBaseCommand *)[notification
objectForKey:uveSetTopBoxCommandKey];
|
if ([baseCommand isKindOfClass:[uveRecordingsCommand class]]){
|
uveRecordingCommand *recordingsCommand = (uveRecording
*)baseCommand;
|
// handle for uveRecordingCommand
| } else if ([baseCommand isKindOfClass:[uveRemoteKeyCommand
class]]){
| // handle for uveRemoteKeyCommand
| }
Example 4-6: commandSucceeded
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 12 of 25
5 SetTopBoxPickerTableViewController Design
The purpose of the SetTopBoxPickerTableViewController, which inherits from
UITableViewController, is to display a list of the SetTopBoxes that the user has
on their local network. The list that is constructed includes any SetTopBoxes that
are in Default mode (those that do not require a passcode to engage), or Custom
mode (those that require the user to enter a passcode on first time engagement).
If there are any SetTopBoxes in UverseModeUnknown, it means that the user
has not yet enabled the U-verse Enabled features on those U-verse receivers.
The user is also able to disable the U-verse Enabled functionality on a U-verse
receiver. In this case the U-verse receiver will be in Closed Mode.
To handle the case of receivers in Closed or Unknown mode, an extra row in the
tableview is displayed called “Add New Receiver”, with instructions for the user
on how to enable the U-verse Enabled features on their SetTopBox. If there are
any receivers in UverseModeClosed or UverseModeUnknown, they should not
be displayed in the list, and instead the “Add New Receiver” cell should be
displayed.
Figure 5-1: SetTopBoxPickerTableViewController
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 13 of 25
5.1 Implementing the viewDidLoad Method
The viewDidLoad method performs the following actions:

Setting up the UINavigationBar with a title (“Receivers”) and a button that
allows the user to cancel out of the Model view and go back to the main
viewController for the app (the RemoteControlViewController).

Calling the registerForNotifications method which registers for the
Notifications necessary to handle the engagement process.

Calling the setupListOfstb method. This method prepares the model (a list
of SetTopBoxes) that the tableview will use.
The following code shows the implementation of the viewDidLoad method.
viewDidLoad
1
2
3
4
5
6
7
8
9
10
11
| - (void)viewDidLoad
| {
|
[super viewDidLoad];
|
[self registerForNotifications];
|
self.title = @"Receivers";
|
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc]
initWithTitle:@"Close" style:UIBarButtonItemStyleBordered
target:self action:@selector(close:)];
|
self.navigationItem.leftBarButtonItem = closeButton;
|
[closeButton release];
|
|
[self setupListOfstb];
| }
Example 5-1: viewDidLoad
5.2 Implementing the registerForNotifications Method
The following code shows the implementation of the registerForNotifications
method that is called from viewDidLoad of the
SetTopBoxPickerTableViewController. In the registerForNotifications
method, the two notifications that you will need to observe are
uveSetTopBoxEngagementDidFail and uveSetTopBoxEngagementDidSucceed.
With the update to fast discovery caching with the 3.0 library, you should now
also listen for the UverseConnectedManagerSetTopBoxUpdated notification,
which will informed you that the property SetTopBoxes on the
UverseConnectedManager has been updated.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 14 of 25
registerForNotifications
1
2
3
4
5
6
7
11
| -(void)registerForNotifications
| {
|
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(uvcSTBAssociationDidFail:) name:
uveSetTopBoxEngagementDidFail object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(uvcSTBAssociationDidSucceed:) name:
uveSetTopBoxEngagementDidSucceed object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(uvcSTBAssociationDidSucceed:)
name:uveSetTopBoxCommandDidSucceed object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(uvcSTBAssociationDidFail:)
name:uveSetTopBoxCommandDidFail object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(uveMgrSetTopBoxesUpdated:)
name:UverseConnectedManagerSetTopBoxesUpdated object:nil];
| }
Example 5-2: registerForNotifications
5.3 Implementing the uveSetTopBoxEnagagementDidSucceed
notification Callback Method
The callback for uveSetTopBoxEngagementDidSucceed (shown here) simply
dismisses the SetTopBoxPicker and returns to the main view controller.
uveSetTopBoxEnagagementDidSucceed
1
2
3
4
| -(void)uvcSTBAssociationDidSucceed:(NSNotification *)notification
| {
|
[self.presentingViewController
dismissModalViewControllerAnimated:YES];
| }
Example 5-3: uveSetTopBoxEnagagementDidSucceed
5.4 Implementing the uveSetTopBoxEnagagementDidFail
notification Callback Method
The following code shows the cases from the uveSetTopBoxEngagementDidFail
notification. For the two cases uveNotOnAUverseNetwork and uveNetworkError,
an info view controller is displayed to the user to show details of the problem.
This is a simple view controller that is in the sample code, but the details of it will
not be discussed here. The uveNonceInvalid case occurs when the user enters
the wrong passcode. In this case, the method checks to see if the
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 15 of 25
PasswordViewController is the currently displayed view controller, and if it is, the
user is prompted to re-enter the passcode.
uveSetTopBoxEnagagementDidFail notification
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| -(void)uvcSTBAssociationDidFail:(NSNotification *)notification{
|
NSDictionary *userInfo = [notification userInfo];
|
NSError *error = [userInfo
objectForKey:UverseConnectedManagerErrorKey];
|
switch (error.code) {
|
case uveNonceInvalid:
|
NSLog(@"NOTIFICATION
uvcSetTopBoxAssociationDidFail:uveNonceInvalid");
|
if ([self.navigationController.visibleViewController
isKindOfClass:[PasswordViewController class]]){
|
PasswordViewController *passwordController =
(PasswordViewController
*)self.navigationController.visibleViewController;
|
passwordController.bottomLabel.textColor =
[UIColor redColor];
|
passwordController.bottomLabel.text = @"Please
retry Password";
|
}
|
break;
|
|
case uveNotOnAUverseNetwork: {
|
NSLog(@"NOTIFICATION
uvcSetTopBoxAssociationDidFail:uvcNotOnAUverseNetwork");
|
InfoViewController *noUverseViewController =
[[InfoViewController alloc]
initWithStyle:uvcNotOnAUverseNetworkStyle];
|
UINavigationController *navController =
[[UINavigationController alloc]
initWithRootViewController:noUverseViewController];
|
[self presentModalViewController:navController
animated:YES];
|
[noUverseViewController release];
|
[navController release];
|
break;
|
}
|
|
case uveNetworkError:{
|
NSLog(@"NOTIFICATION
uvcSetTopBoxAssociationDidFail:uvcNetworkError");
|
InfoViewController *networkViewController =
[[InfoViewController alloc] initWithStyle:uvcNetworkErrorStyle];
UINavigationController *nav2Controller =
[[UINavigationController alloc]
initWithRootViewController:networkViewController];
[self presentModalViewController:nav2Controller
animated:YES];
[networkViewController release];
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 16 of 25
30
31
32
[nav2Controller release];
break;
|
}
Example 5-4: uveSetTopBoxEnagagementDidFail notification
5.5 Implementing the
UverseConnectedManagerSetTopBoxesUpdated Notification
Callback Method
The callback for UverseConnectedManagerSetTopBoxesUpdated (shown here)
simply calls the setupListOfstb method (described in the next section).
UverseConnectedManagerSetTopBoxesUpdated
1
2
3
4
| -(void)uveMgrSetTopBoxesUpdated:(NSNotification *)notification
| {
|
[self setupListOfstb];
| }
Example 5-5: UverseConnectedManagerSetTopBoxesUpdated
5.6 Implementing the setupListOfstb Method
The setupListOfstb method performs the following actions:

Sets the unknownSTBs flag to NO.

Clears the list of SetTopBoxes.

Enumerates through the NSArray of the UverseConnectedManager
property SetTopBoxes, and adds any SetTopBoxes that are in the open
(UverseModeOpen) or managed (UverseModeManaged ) modes to the list
that will be displayed in the tableView. If any SetTopBoxes are in the
UverseModeUnknowns state, the unknownSTBs flag will be set to YES.

Sorts the list in alphabetical order.
The following code shows the implementation of the setupListOfstb method.
setupListOfstb
1
2
3
4
5
| -(void)setupListOfstb{
|
unknownSTBs = NO;
|
UverseConnectedManager *uvcMgr = [UverseConnectedManager
sharedManager];
|
[self.list removeAllObjects];
|
for (SetTopBox *stb in [uvcMgr SetTopBoxes]){
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 17 of 25
6
7
8
|
|
|
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23
|
24
25
|
|
switch (stb.mode) {
// if the mode is open or mananged, add the stb to the
list of the stbs to display
case UverseModeOpen:
case UverseModeManaged:
[self.list addObject:stb];
break;
case UverseModeUnknown:
unknownSTBs = YES;
break;
case UverseModeClosed:
break;
default:
break;
}
}
[self.list sortedArrayUsingComparator:^(SetTopBox *first,
SetTopBox *second){
return [first.friendlyName
localizedCaseInsensitiveCompare:second.friendlyName];
}];
}
Example 5-6: setupListOfstb
5.7 Implementing the UITableView:cellForRowAtIndexPath
Method
The UITableView:cellForRowAtIndexPath: method, shown in the following code,
begins by setting up a new cell.
The method then contains the condition if ( indexPath.row < [self.list
count]) which checks whether the row should be for an Open or managed
SetTopBox on the local network, and if this condition fails, a row is displayed at
the end of the tableview for “Add New Receiver”. If the condition is true, the cell
is built by first getting a reference to the SetTopBox for the row and setting the
name of the SetTopBox as the main text of the cell.
If a row in the table for a SetTopBox is being created, there is a check to see
whether the SetTopBox is in UverseModeManaged mode. If it is, the row’s image
is set to be an open lock if the SetTopBox has previously been engaged or if it is
currently engaged while using this app. This means that the user will not need to
enter the four digit passcode when they engage with the receiver. The
isAssociated property of the SetTopBox will return YES if the user has previously
entered the four digit passcode for this U-verse Enabled app. If the U-verse
receiver is in managed mode and the isAssociated property returns YES for the
device and app, the user does not need to enter the four digit passcode again. If
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 18 of 25
the isAssociated property returns NO, the user will need to enter the four digit
passcode before they can engage with the U-verse receiver, and the row’s image
is set to be a closed lock to indicate that the user will need to enter the four digit
passcode before being able to engage with this SetTopBox.
The final check inside this condition checks to see whether the SetTopBox is
currently engaged. If it is engaged, the accessoryType is set to be a checkmark,
otherwise, it is left blank.
UITableView:cellForRowAtIndexPath
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| - (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
| {
|
static NSString *CellIdentifier = @"stbCell";
|
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
|
if (cell == nil){
|
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
|
cell.textLabel.font = [UIFont systemFontOfSize:16];
|
cell.textLabel.textColor = [UIColor blackColor];
|
cell.imageView.image = nil;
|
cell.accessoryType = UITableViewCellAccessoryNone;
|
}
|
|
if (indexPath.row < [self.list count] ){
|
|
// Configure the cell...
|
SetTopBox *listSTB = [self.list
objectAtIndex:indexPath.row];
|
// setup the name
|
cell.textLabel.text = listSTB.friendlyName;
|
|
// check wether to display the lock
|
if (listSTB.mode = UverseModeManaged){
|
if (listSTB.isAssociated || listSTB.isEngaged){
|
cell.imageView.image = [UIImage
imageNamed:@"PairingUnlock.png"];
|
} else {
|
cell.imageView.image = [UIImage
imageNamed:@"PairingLock.png"];
|
cell.accessoryType =
UITableViewCellAccessoryDisclosureIndicator;
|
}
|
}
|
|
if (listSTB.isEngaged && listSTB ==
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 19 of 25
31
|
32
33
34
35
36
37
38
39
40
41
|
|
|
|
|
|
|
|
|
|
[UverseConnectedManager
sharedManager].mostRecentlyEngagedSetTopBox){
cell.accessoryType =
UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryView = nil;
cell.accessoryType = UITableViewCellAccessoryNone;
}
} else {
cell.textLabel.textColor = [UIColor blueColor];
cell.textLabel.text = @"Add New Receiver...";
}
return cell;
}
Example 5-7: UITableView:cellForRowAtIndexPath
5.8 Implementing the didSelectRowAtIndexPath Method
The didSelectRowAtIndexPath method, shown in the following code, tests the
mode of the selected SetTopBox to see whether it is open or engaged.
The method contains a main test that checks whether the row is less than the
size of the list. If this is true, it indicates that the item is a SetTopBox. If this
condition fails, the flow for engaging a new SetTopBox is started by calling the
displayLinkingInfoController method.
Inside this branch, the mode of the SetTopBox is checked. If the SetTopBox is in
the UverseModeOpen mode, it will be engaged and the app will return to the
main view Controller.
If the SetTopBox is in the UverseModeManaged mode, the method checks
whether the SetTopBox has previously been engaged, by checking the
isAssociated property of the SetTopBox. If it has been, it will engage again and
the app will return to the main screen. If this condition fails, a new view controller
will be displayed for the user to enter the passcode and connect with the
SetTopBox.
didSelectRowAtIndexPath
1
2
3
4
5
6
| -(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
| {
|
[self.tableView deselectRowAtIndexPath:indexPath
animated:YES];
|
if (indexPath.row < [self.list count]) {
|
self.currentSTB = [self.list objectAtIndex:indexPath.row];
|
switch (self.currentSTB.mode) {
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 20 of 25
7
8
9
|
|
|
10
11
12
|
|
|
13
14
|
|
15
16
17
18
19
20
21
22
23
24
25
26
|
|
|
|
|
|
|
|
|
|
|
|
case UverseModeOpen:{
[self.currentSTB engage];
[self.presentingViewController
dismissModalViewControllerAnimated:YES];
break;
case UverseModeManaged:{
if (YES == self.currentSTB.isAssociated || YES ==
self.currentSTB.isEngaged) {
[self.currentSTB engage];
[self.presentingViewController
dismissModalViewControllerAnimated:YES];
} else {
[self displayPasswordController];
}
break;
}
default:
break;
}
// END switch
}else {
[self displayLinkingInfoController];
}
}
Example 5-8: didSelectRowAtIndexPath
5.9 Implementing the PasswordViewController Delegate Method
The final method in the SetTopBoxPickerTableViewController is the
PasswordViewController delegate method. The purpose of this method is to
send the passcode to the setTopBox for processing and rely on the notification
callbacks setup earlier for the failed or succeed states of this command.
PasswordViewController
1
2
3
4
| - (void)passwordController:(PasswordViewController *)controller
checkPassword:(NSString *)password {
|
NSLog(@"password: %@", password);
|
[self.currentSTB associateAndEngageWithOneTimeToken:password];
| }
Example 5-9: PasswordViewController
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 21 of 25
6 PasswordViewController Design
The purpose of the passwordViewController is to take a passcode entered by the
user and send that passcode to its delegate to check whether the correct
passcode was entered.
This class was designed to be as reusable as possible, and for this reason, it
does not perform any interaction with the U-verse Enabled subsystem. It simply
passes the passcode to its delegate (the SetTopBoxPickerTableViewController in
this code example), to be processed.
The design of this viewController uses a hidden text field that stores the
passcode and captures the input from the keyboard. It then sets the digits into
the text fields that are displayed to the users. It’s important to note that the
passwordHiddenField is not setup as a property, because this variable must not
be exposed outside of the class.
Figure 6-1: PasswordViewController
6.1 Implementing the viewDidLoad Method
The viewDidLoad method, performs the following actions:

Sets up the passwordHiddenField with a frame of CGRectZero, a zero sized
rect.
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 22 of 25

Sets the delegate to be the PasswordViewController.

Sets the keyboard type to be the number pad.

Calls becomeFirstResponder so the keyboard will be displayed on load.

Sets up the title and a label with the name of the SetTopBox.
The following code shows the implementation of the viewDidLoad method.
viewDidLoad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| - (void)viewDidLoad {
|
[super viewDidLoad];
|
|
passwordHiddenField = [[UITextField alloc]
initWithFrame:CGRectZero];
|
passwordHiddenField.delegate = self;
|
passwordHiddenField.keyboardType = UIKeyboardTypeNumberPad;
|
passwordHiddenField.text = @"";
|
[passwordHiddenField becomeFirstResponder];
|
[self.view addSubview:passwordHiddenField];
|
|
// Do any additional setup after loading the view from its
nib.
|
self.navigationItem.title = @”Enter your Passcode");
|
self.topLabel.text = [NSString stringWithFormat: @"Using your
U-verse remote, tune to channel 9301 on receiver %@",
self.delegate.currentSTB.friendlyName];
| }
Example 6-1: viewDidLoad
The passwordEntered method calls the checkPassword method of the
delegate. passwordEntered is called when the user enters the four digit
passcode.
passwordEntered
1
2
3
4
5
6
7
| - (void)passwordEntered:(NSString *)password {
|
//self.waitView = [[ProgressIndictator
alloc]initWithTitleLabelText:@"Please Wait"
andInfoLabelText:@"Checking Passcode"];
|
| if (self.delegate && [self.delegate
respondsToSelector:@selector(passwordController:checkPassword:)]){
|
[self.delegate passwordController:self
checkPassword:password];
|
}
| }
Example 6-2: passwordEntered
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 23 of 25
The UITextFieldDelegate method
shouldChangeCharactersInRange:replacementString: is used to update the
characters in the one character text fields on the screen. This method is the
delegate for the UITextField called passwordHiddenField that was set in the
viewDidLoad method.
The shouldChangeCharactersInRange:replacementString: method uses the
length of the characters in the passwordHiddenField, and then updates the four
password test fields that are displayed to the user. After the user has entered
four characters, the passwordEntered method is called.
shouldChangeCharactersInRange:replacementString: Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| - (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
|
NSString *password = [textField text];
|
password = [password stringByReplacingCharactersInRange:range
withString:string];
|
|
switch ([password length]) {
|
case 0:
|
self.passwordField0.text = nil;
|
self.passwordField1.text = nil;
|
self.passwordField2.text = nil;
|
self.passwordField3.text = nil;
|
break;
|
case 1:
|
self.passwordField0.text = [password
substringWithRange:NSMakeRange(0, 1)];
|
self.passwordField1.text = nil;
|
self.passwordField2.text = nil;
|
self.passwordField3.text = nil;
|
break;
|
case 2:
|
self.passwordField0.text = [password
substringWithRange:NSMakeRange(0, 1)];
|
self.passwordField1.text = [password
substringWithRange:NSMakeRange(1, 1)];
|
self.passwordField2.text = nil;
|
self.passwordField3.text = nil;
|
break;
|
case 3:
|
self.passwordField0.text = [password
substringWithRange:NSMakeRange(0, 1)];
|
self.passwordField1.text = [password
substringWithRange:NSMakeRange(1, 1)];
|
self.passwordField2.text = [password
substringWithRange:NSMakeRange(2, 1)];
|
self.passwordField3.text = nil;
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 24 of 25
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
|
|
break;
case 4:
self.passwordField0.text = [password
substringWithRange:NSMakeRange(0, 1)];
|
self.passwordField1.text = [password
substringWithRange:NSMakeRange(1, 1)];
|
self.passwordField2.text = [password
substringWithRange:NSMakeRange(2, 1)];
|
self.passwordField3.text = [password
substringWithRange:NSMakeRange(3, 1)];
|
|
[self performSelector:@selector(passwordEntered:)
withObject:password afterDelay:0];
|
|
return NO;
|
|
break;
|
default:
|
return NO;
|
break;
|
}
|
|
return YES;
|
| }
Example 6-3: shouldChangeCharactersInRange:replacementString: Method
© 2013 AT&T Intellectual Property. All rights reserved. AT&T and the AT&T logo are trademarks of AT&T Intellectual Property.
Page 25 of 25