This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How do you use State Preservation and Restoration in iOS?

I have been working on an application for iOS for a few months now, and I want to give my users the best experience possible, when it comes to the peripheral I intend to use with the app, and in order to do that, I would like to be able to use state preservation and restoration to connect to my peripheral, in case the application has been suspended by the OS at some point.

So far, I have only managed to implement a bit of code, following the guide on Apple's developer pages, but without success. If anybody could help me with this, I would be very grateful.

Here is my code:

// AppDelegate.m, didFinishLaunchingWithOptions:

    manager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)options:@{CBCentralManagerOptionRestoreIdentifierKey:@"myManager"}];

// AppDelegate.m, willRestoreState:

    NSArray *peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey];
    if (dict[CBCentralManagerRestoredStatePeripheralsKey]) {
        for (CBPeripheral *currentPeripheral in peripherals) {
            peripheral = currentPeripheral;
        }
        [mainController connect: peripheral :manager]; // Connects to the peripheral
    }
    else{
        [mainController scan: manager]; // Scans for the peripheral
    }

I am only using one peripheral, and I am only using one central.

Thank you.

  • In Apple documentation, https://goo.gl/DHYPMm There are 3 ways to get the peripheral.

    1- retrievePeripheralsWithIdentifiers: for known peripherals and you need peripheral identifier (NSUUID).

    2- retrieveConnectedPeripheralsWithServices: for connected peripherals and you need to provide Primary Bluetooth LE Service (CBService).

    3- scanForPeripheralsWithServices: for unknown peripherals.

    In order to retrieve known peripheral you must save peripheral identifier. you can use NSUserDefault to save and retrieve the peripheral identifier.

    //save peripheral identifier using NSUserDefault
    
    NSUserDefaults *perId = [NSUserDefaults standardUserDefaults];
    
    [perId setObject:[peripheral.identifier] forKey:@"peripheralIdentifier"];
    
    [perId synchronize];
    
    //retrive peripheral identifier when next time user launch app
    
    NSUserDefaults *perId = [NSUserDefaults standardUserDefaults];
    
    NSUUID *peripheralIdentifier = [perId objectForKey:@"peripheralIdentifier"];
    
    //Retrive know peripheral by giving the identifier
    
    NSArray *peripherals = [self.centralManager 
    retrievePeripheralsWithIdentifiers:@[peripheralIdentifier]];
    
    if ([peripherals count]>0)
    
    {
          CBPeripheral *peripheral=[peripherals objectAtIndex:0];
    
          peripheral.delegate=self;
    
          [self.connectingPeripherals addObject:peripheral];
    
          NSLog(@"Retrieved Known peripheral %@ its name %@",peripheral.identifier,peripheral.name);
    
         [self.centralManager connectPeripheral:peripheral options:nil]; 
    
         } else {
    
         //scan peripheral
    
         }
    
  • So, the only thing I did right was the initialisation of the centralManager? I will try to use NSUserDefaults, and then I just write the retrieval part in my willRestoreState method?

  • hopefully it will work, if not then just let us know :)

  • I will, thank you so much. I'm pretty new to iOS, and I really want to get this done, so I really appreciate your help a lot. Fingers crossed!

  • I am saving my peripheral identifier in my didConnectPeripheral method, I am retrieving the identifier in my didFinishLaunchingWithOptions method, and I am trying to reconnect, or scan, in my willRestoreState method. Does that sound right?

Related