views:

433

answers:

1

I have my app set up to send a custom level in a form of a array to another person during a p2p connection. The receiving device saves the array to file for later use. I set up gamekit in my application, it will successfully search and connect to another device without any problems. Though a problem arises when I send data to a device, the receiving device will receive the data (and save the custom level like it should) but it will immediately crash afterwords.

Here are my methods that I use to send and receive data.

-(void) sendDataToPeers:(NSData *) data
{
    if (currentSession) 
    {
        //send the data
        [self.currentSession sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];   

        //Alerting the user that the custom level has been sent.
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sent!" message:@"Your custom level has been sent." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
}

-(void) btnSend
{
    //Data that will be sent
    NSMutableData *theData = [NSMutableData data];

    //Archiver
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];

    //Desired level to send
    int theLevel =[[CTManager sharedInstance]getLevel];

    //Path to the custom levels
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory=[paths objectAtIndex:0];
    NSString *customLevelsSen = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"customLevels"]];

    //Custom levels array
    NSArray *theLevels = [[NSArray alloc] initWithContentsOfFile: customLevelsSen];

    //Gets the desired level array from array of custom levels
    NSArray *myArray = [[NSArray alloc]initWithArray:[theLevels objectAtIndex:theLevel-51]];

    //prepare data
    [archiver encodeObject:myArray forKey:@"level"];
    [archiver finishEncoding];

    //send the data
    [self sendDataToPeers:theData];

    //cleanup
    [archiver release];
    [theLevels release];
    [myArray release];

}

-(void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context 
{   
    //Archiver
    NSKeyedUnarchiver *archiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

    //Gets the custom level in form of an array from data.
    NSArray *level = [archiver decodeObjectForKey:@"level"];
    [archiver finishDecoding];
    [archiver release];

    //Path to the array of custom levels
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory=[paths objectAtIndex:0];
    NSString *customLevelsRec = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"customLevels"]];

    //Gets the array of custom levels
    NSMutableArray *customLevelArray = [[NSMutableArray alloc] initWithContentsOfFile:customLevelsRec];

    //Adds a new array to the array of custom levels
    [customLevelArray addObject:level];

    //Saves the array.
    [customLevelArray writeToFile:customLevelsRec atomically:YES];

    //cleanup
    [customLevelArray release];

    //Message saying a custom level has been recieved
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Received!" message:@"A custom level has been saved." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
    [alert release];

}

Testing this has been a pain since I don't have two devices of my own currently, so I send a beta build to my friend who inturns tests them (he has ipod and iphone). Any help with this is appreciated...

If I can't find the problem I will most likely send the entire xcode project to him and via screen share work with the project on his computer to efficiently build and test the application. And I will be able to use debug mode.

A: 

I don't see anything wrong in your receiveData method.

Have you checked that the folder where you are trying to save the data (customLevels) exists?

I have succeeded to connect via an application using GameKit a device and the iPhone simulator. It's really handy to debug.
I haven't check if it was by bluetooth or wifi.

Guillaume
Upon installation of the app that file is created. The file is getting saved to the receiving device but it just crashes afterward. Once you relaunch the app the file is there. A bit ago I took the main parts of the send and receive method and put them into one function (for testing purposes) that would get called each time I clicked a send button. This way I could test my logic with only one device, the test method successfully worked by simply duplicating the level. It archived the data then unarchived the data and placed into the "customLevels" file in the same device.
Avizzv92
"I have succeeded to connect via an application using GameKit a device and the iPhone simulator. It's really hand to debug.I haven't check if it was by bluetooth or wifi." I heard you can do it with wifi, but if it was bluetooth can you explain how you did it?
Avizzv92
I finally checked, and could not get it to work over Bluetooth. Sorry for the false hope. Using wifi, it works really well. (I am connecting with the sessionMode: GKSessionModePeer)
Guillaume
When you save the array to file, what is the return value of <code>- writeToFile: atomically:</code> ?The delegate of your UIAlertView is self. Have you implemented the delegate methods of the UIAlertViewDelegate protocol?
Guillaume