Odd GCController behavior when Apple TV Remote mobile app is connected

Whenever the only remote attached to the Apple TV is an iOS Apple TV Remote app, the GCController object is connected and disconnected each time the tvOS app didResignActive:. This seems to be fine, the problem comes in the object passed with the GCControllerDidConnectNotification and GCControllerDidDisconnectNotification notifications.


When first starting the app, I receive:


Connected: <GCController 0x1c80a6b40 vendorName='Remote' deviceHash=0x113f884c0>

[GCController controllers]: (

"<GCController 0x1c80a6b40 vendorName='Remote' deviceHash=0x113f884c0>"

)

And then, if I long press the Home button to bring up the sleep dialog, I see:

Disconnected: <GCController 0x1c80a8a60 vendorName='Remote' deviceHash=0x113f884c0>

[GCController controllers]: (

"<GCController 0x1c80a6b40 vendorName='Remote' deviceHash=0x113f884c0>"

)

Notice at this point that the GCController that was disconnected (0x1c80a8a60) is a different object than the one that was connected (0x1c80a6b40).


I then dismiss the sleep dialog (either hit menu or cacel) and then I see:


Connected: <GCController 0x1c80a8a60 vendorName='Remote' deviceHash=0x113f88d10>

[GCController controllers]: (

"<GCController 0x1c80a8a60 vendorName='Remote' deviceHash=0x113f88d10>"

)

Notice that this is yet another new GCController object (0x1c80a8a60). So at this point in time, if I debug the memory graph. I can indeed see that their are three GCController objects pertaining to each of the ones listed above (0x1c80a6b40,0x1c80a8a60, and0x1c80a8a60) being retained by the same _GCControllerManager.


This by itself isn't a very big issue for me, the bigger issue is that if you continue to background (resign active) the app, valueChangedHandlers on the

GCControllerDirectionPad eventually stops being called. I set the valueChangedHandler on the dpad every single time a controller is connected (as shown below), but eventually it just stops getting called.

Is this a known issue?


Here is the code I used to demo this behavior.


#import "ViewController.h"

#import <GameKit/GameKit.h>

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

NSNotificationCenter* notifications = NSNotificationCenter.defaultCenter;

[notifications addObserver:self

selector:@selector(controllerConnected:)

name:GCControllerDidConnectNotification

object:nil];

[notifications addObserver:self

selector:@selector(controllerDisconnected:)

name:GCControllerDidDisconnectNotification

object:nil];

}

- (void)controllerConnected:(NSNotification*)notification {

GCController* controller = (GCController*)notification.object;

NSLog(@"Connected GCController %p", controller);

NSLog(@"GCControllers: %@", [GCController controllers]);


controller.microGamepad.dpad.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {

NSLog(@"dpad.valueChangedHandler called");

};

}

- (void)controllerDisconnected:(NSNotification*)notification {

GCController* controller = (GCController*)notification.object;

NSLog(@"Disconnected GCController %p", controller);

NSLog(@"GCControllers: %@", [GCController controllers]);

}

@end