2

EDIT: I get the following error codes:

Error adding accessory The operation couldn’t be completed. (HMErrorDomain error 2.)

And:

Error adding accessory Failed to start pairing with the accessory [ name = xxxxx, providedName = xxxxx, uuid = xxxxx-xxxxx-xxxxx-xxxxx-xxxxx, identifier = xxxxx, configuration-app-id = (null), home = (null), bridge = (null) ]

Both with number 2.

What I don't understand is why on the HMCatalog app this works. What's wrong with my code? It works fine on the Accessory simulator but not on the real accessory (the real accessory is added only via the HMCatalog app but not my custom app).


Actual Behaviour:

  • add accessory from my app (works the first time)
  • reset accessory and then re-add it (does not work and gives pairing error in screenshot below). However when it does give those errors if I use the Apple example HMCatalog it does work.

enter image description here

And sometimes:

enter image description here

Expected results:

  • adds accessory from my app too without pairing error

This is my add accessory code:

 [self.home addAccessory:self.accessory completionHandler:^(NSError *error) {
        NSLog(@"in adding for accessory %@", self.accessory.name);
        if (error) {
            NSLog(@"Error adding accessory %@ %li", error.localizedDescription, (long)error.code);

            UIAlertController *alertController = [UIAlertController
                                                  alertControllerWithTitle:@"Pairing error"
                                                  message:error.localizedDescription
                                                  preferredStyle:UIAlertControllerStyleAlert];

            UIAlertAction *okAction = [UIAlertAction
                                       actionWithTitle:NSLocalizedString(@"OK", @"OK action")
                                       style:UIAlertActionStyleDefault
                                       handler:^(UIAlertAction *action)
                                       {
                                           NSLog(@"OK action");
                                       }];

            [alertController addAction:okAction];
            [self presentViewController:alertController animated:YES completion:nil];

        }
        else{
            // TODO: Tweak this
            NSLog(@"Added to home");

            [self dismiss:nil];
            /**
             [homeSweetHome assignAccessory:accessory toRoom:nil completionHandler:^(NSError *error) {
             if (error) {
             NSLog(@"Failed adding accessory %@ to room %@", accessory.name, room.name);
             }
             }];**/
        }
    }];
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
mm24
  • 9,280
  • 12
  • 75
  • 170
  • That first error doesn't look like it's coming from homekit (it isn't something from HMErrorDomain, and doesn't show an HMErrorCode). Does the error have a code? Where are the home and accessory coming from? And why are you reassigning your properties to __block vars? – Adam Shiemke Aug 25 '15 at 16:55
  • I created the home in the HMCatalog app, the accessory is a real accessory. I used blocks as it was an asynchronous method, now I removed them. Will tell u the error code shortly. – mm24 Aug 25 '15 at 21:37
  • @AdamShiemke the error code is "2" – mm24 Aug 25 '15 at 21:45
  • I am getting the same error as you. There seems to be some bugs when you remove an accessory and add it again... or use the reset button in the simulator. HomeKit doesn't like repairing accessories it seems. – Josh Gafni Sep 09 '15 at 03:09
  • have you found a solution for this?? I'm currently facing this issue on my app – Tushar Koul Oct 20 '15 at 23:19
  • Not really unfortunately.. there must be something somewhere with a clear documentation on error codes.. it cannot be just in the code.. – mm24 Oct 21 '15 at 12:04
  • @mm24 I was thinking about how you get a reference to `self.accessory`. In my code i pick up the reference from the `discoveredAccessories` array in the `HMAccessoryBrowser`. MAYBE we have to use the accessory object that is passed as a parameter to `didFindAccessory`delegate method. – Tushar Koul Oct 21 '15 at 13:45
  • @TusharKoul you're probably right. Looking at the code for my app, I have a local array that I fill from the delegate, and I never use the discoveredAccessories array. – Adam Shiemke Oct 21 '15 at 22:42

2 Answers2

2

EDIT: per Tushar Koul's comment above, it looks like you need to ignore the discoveredAccessories array on the browser and instead construct your own array of objects from the accessoryBrowserDelegate (-accessoryBrowser:didFindNewAccessory and -accessoryBrowser:didRemoveAccessory).

After telling the browser to start searching, any accessories currently available will be passed to those methods.

HMErrorCode 2 is not found (see apple docs). This means that the accessory pointer that you have isn't valid anymore. This can be caused by grabbing an accessory object and then telling the accessory browser to start looking for accessories. It might also happen if the browser is deallocated before you add the accessory.

Make sure that you are getting a new HMAccessory for the HMAccessoryBrowser before you try to add the accessory to your home. If you can share more of the code showing where the HMAccessory that you're adding is coming from, I might be able to help more.

Adam Shiemke
  • 3,734
  • 2
  • 22
  • 23
  • I checked my code and the accessory and accessory browser object are not nill.. really don't understand what is happening.. also the accessory seems to be reachable.. I will try to simplify my code and paste it here.. – mm24 Aug 26 '15 at 09:14
2

After 5 different combinations and several hours of testing, here are my findings -

  1. HMAccessoryBrowser's instantiation should happen way before we start searching for homekit devices.

I had this in my viewDidLoad in consecutive lines and it DID NOT work a 100% of the time

  self.accessoryBrowser = [HMAccessoryBrowser alloc] init]; 
[self.accessoryBrowser startSearchingForNewAccessories];

E.g. If you use it in a view controller then that view controllers code should look like -

    -(instanceType)init{  
if(self = [super init]){   
self.accessoryBrowser = [HMAccessoryBrowser alloc] init];  } 
}

    -(void)viewDidLoad{ 
[self.accessoryBrowser startSearching];
 }

So I reckon you should initialise HMAccessoryBrowser before.

  1. The instance of HMAccessoryBrowser should be alive until the addition of accessory to home is complete.

  2. Do not call stopSearchingForNewAccessories until the addition of accessory to home is complete.

So talking about #2 and #3

  • you find the device after calling startSearchingForNewAccessories , then you call [self.home addAccessory: completion:] on it.

Until you complete this operation successfully, DO NOT call stopSearchingForNewAccessories and keep the instance of HMAcccessoryBrowser alive.

I was searching for my homekit accessory, on finding it I would stop searching and then try to add the accesory to my home. I would get the ErrorCode 2 almost every single time. Once I stopped calling stopSearching i was seeing better results

  1. I have my doubts on using the object reference from the discoveredAccessories array. Instead, I would recommend using the object received from the delegate callback

- (void)accessoryBrowser:(HMAccessoryBrowser *)browser didFindNewAccessory:(HMAccessory *)accessory

Tushar Koul
  • 2,830
  • 3
  • 31
  • 62