IT tutorials

iPhone SDK 3 : Making Connections with GameKit and Bonjour - Working Around Real-World GameKit Limitations

3/4/2013 6:37:29 PM
- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire

Although GameKit is built on Bonjour, it isn’t meant to provide the same kind of general use data transfer capabilities displayed in the previous two Bonjour-only recipes. GameKit Bluetooth prefers small data packets, preferably under 1,000 bytes each. GKSession objects cannot send data over 95 kilobytes. When you try, the sendDataToAllPeers:error: method fails, returning a Boolean value of NO.

Recipe 12-7 addresses this problem by checking for data length before queuing any send requests. Short data can be shared; long data is denied. To provide a test bed, this recipe works with the iPhone’s built-in pasteboard.

In the real world, you’d likely split up long data items into short bursts and send them using reliable transfer. Reliable transmission ensures that data arrives and does so in the same order that it was sent. You can implement checksumming and other standard network approaches to ensure your data arrives properly. (You might alternatively consider programming a custom Bonjour WiFi service or using Internet server connections for more intense data transfer needs.)

This recipe provides a jumping off point for testing file size elements in the GameKit world. You are welcome to expand this code to explore file decomposition and reconstruction on your own.

Using the iPhone Pasteboard

Pasteboards, also known as clipboards, provide a central OS feature for sharing data across applications. Users can copy data to the pasteboard in one application, switch tasks, and then paste that data into another application. Cut/copy/paste features appear in most operating systems and are new to the iPhone, having debuted in the 3.0 firmware.

The UIPasteboard class offers access to a shared iPhone pasteboard and its contents. As with Macs and Windows-based computers, you can use the pasteboard to share data within an application or between applications. In addition to the general shared system pasteboard, the iPhone offers both a name finding pasteboard and application-specific pasteboards to better ensure data privacy. This snippet returns the general system pasteboard, which is appropriate for most general copy/paste use.

UIPasteboard *pb = [UIPasteboard generalPasteboard];

Storing Data

Pasteboards can store one or more entries at a time. Each has an associated type, using the Uniform Type Identifier (UTI) to specify what kind of data is stored. For example, you might find public.text (and more specifically public.utf8-plain-text), public.url, and public.jpeg among common data types used on the iPhone. The dictionary that stores the type and the data is called an item, and you can retrieve an array of all available items via the pasteboard’s items property.

Query a pasteboard for its available types by sending it the pasteboardTypes message. This returns an array of types currently stored on the pasteboard.

NSArray *types = [pb pasteboardTypes];

Pasteboards are specialized for several data types. These are colors, images, strings, and URLs. The UIPasteboard class provides specialized getters and setters to simplify handling these items. Because Recipe 12-7 provides a general pasting tool, only strings are demonstrated with a specialized call, that is, setString.

Retrieving Data

Retrieve data using dataForPasteboardType:. This returns the data from the first item whose type matches the one sent as the parameter. Any other matching items in the pasteboard are ignored. Should you need to retrieve all matching data, recover an itemSetWithPasteboardTypes: and then iterate through the set to retrieve each dictionary. Recover the data type for each item from the single dictionary key and the data from its value.

UIPasteboard offers two approaches for pasting to the pasteboard. Use setValueForPasteboardType: for Property List objects. For general data, use setData:forPasteboardType: as is used in this recipe. When pasteboards are changed, they issue a UIPasteboardChangedNotification, which you can listen into via a default NSNotificationCenter observer.

Responsible Pasteboarding

Recipe 1 provides several checks before sending, retrieving, and copying pasteboard data. Users must confirm that they intend to share data of a given type. When receiving data, they must authorize the application to copy the data to the general system pasteboard. This approach ensures that proactive user effort must take place before performing these actions.

Recipe 1. Sharing the iPhone Pasteboard over GameKit
@implementation TestBedViewController

- (void) sharePasteboard
    // Construct a dictionary of the pasteboard type and data
    NSMutableDictionary *md = [NSMutableDictionary dictionary];
    UIPasteboard *pb = [UIPasteboard generalPasteboard];
    NSString *type = [[pb pasteboardTypes] lastObject];
    NSData *data = [pb dataForPasteboardType:type];
    [md setObject:type forKey:@"type"];
    [md setObject:data forKey:@"data"];

    // Deny any requests that are too big
    if (data.length > (95000))
        [ModalAlert say:@"Too much data in pasteboard (%0.2f \
            Kilobytes). GameKit can only send up to approx 90 \
            Kilobytes at a time.", ((float) data.length) / 1000.0f];
    // User must confirm share
    NSString *confirmString = [NSString stringWithFormat:
        @"Share %d bytes of type %@?", data.length, type];
    if (![ModalAlert ask:confirmString]) return;

    // Serialize and send the data
    NSString *errorString;
    NSData *plistdata = [NSPropertyListSerialization
        dataFromPropertyList:md format:NSPropertyListXMLFormat_v1_0
    if (plistdata)
        [GameKitHelper sendData:plistdata];

- (void) sentData:(NSString *) errorString
    // Check to see if there was a problem sending data
    if (errorString)
        [ModalAlert say:@"Error sending data: %@", errorString];

    [ModalAlert say:@"Pasteboard data successfully queued for\

// On establishing the connection, allow the user to share the pasteboard
- (void) connectionEstablished
    UIPasteboard *pb = [UIPasteboard generalPasteboard];
    NSArray *types = [pb pasteboardTypes];
    if (types.count == 0) return;

    self.navigationItem.leftBarButtonItem = BARBUTTON(
        @"Share Pasteboard", @selector(sharePasteboard));

// Hide the share option when the connection is lost
- (void) connectionLost
    self.navigationItem.leftBarButtonItem = nil;

-(void) receivedData: (NSData *) data
    // Deserialize the transmission
    CFStringRef errorString;
    NSDictionary *dict =
        (NSDictionary *) CFPropertyListCreateFromXMLData(
        kCFAllocatorDefault, (CFDataRef)data,
        kCFPropertyListMutableContainers, &errorString);
    if (!dict)

    // Retrieve the type and data
    NSString *type = [dict objectForKey:@"type"];
    NSData *sentdata = [dict objectForKey:@"data"];
    if (!type || !sentdata) return;

    // Do not copy to pasteboard unless the user permits
    NSString *message = [NSString stringWithFormat:
        @"Received %d bytes of type %@. Copy to pasteboard?",
        sentdata.length, type];
    if (![ModalAlert ask:message]) return;

    // Perform the pasteboard copy
    UIPasteboard *pb = [UIPasteboard generalPasteboard];
    if ([type isEqualToString:@"public.text"])
        NSString *string = [[[NSString alloc] initWithData:sentdata
            encoding:NSUTF8StringEncoding] autorelease];
        [pb setString:string];
    else [pb setData:sentdata forPasteboardType:type];

- (void) viewDidLoad
    // Set up the helper
    [GameKitHelper sharedInstance].sessionID = @"Pasteboard Share";
    [GameKitHelper sharedInstance].dataDelegate = self;
    [GameKitHelper assignViewController:self];

- Android : Getting Fancy with Lists - Interactive Rows
- Android : Getting Fancy with Lists - Better. Stronger. Faster.
- Windows Phone 7 : Designing the Game Framework (part 3) - The GameHost Class
- Windows Phone 7 : Designing the Game Framework (part 2) - The TextObject Class
- Windows Phone 7 : Designing the Game Framework (part 1) - The GameObjectBase Class, The SpriteObject Class
- Windows Phone 7 : Getting Started with XNA - Other Graphics Options
- iPad : Your Calendar - Adding New Calendar Appointments, Events (part 2)
- iPad : Your Calendar - Adding New Calendar Appointments, Events (part 1)
- Java ME on Symbian OS : Handling Diversity - Using Adaptive Code and Flexible Design to Handle Diversity
- Java ME on Symbian OS : Handling Diversity - Detecting Diversity using Properties
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
programming4us programming4us
Popular tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS