A simple example of transferring a Mac-to-bluetooth device file?

I spent two days searching the Internet and read the Bluetooth programming guide trying to combine a small Mac application that will extract images from the reset folder and send any new files to a predefined device via Bluetooth. There seem to be few good examples.

I am at a point where I can call the Bluetooth service browser and select the device and its OBEX service, install the service and create a connection, but then nothing else happens. Can someone point me aside / show me a simple example that will work?

Source code for AppDelegate. Thank you for reading!

 #import "AppDelegate.h" @implementation AppDelegate - (void) applicationDidFinishLaunching: (NSNotification *) aNotification {IOBluetoothServiceBrowserController * browser = [IOBluetoothServiceBrowserController serviceBrowserController: 0];  [browser runModal];  // IOBluetoothSDPServiceRecord IOBluetoothSDPServiceRecord * result = [[browser getResults] objectAtIndex: 0];  [self describe: result];  if ([[result.device.name substringToIndex: 8] isEqualToString: @ "Polaroid"]) {printer = result.device;  serviceRecord = result;  [self testPrint];  } else {NSLog (@ "% @ is not a valid device", result.device.name);  }} - (void) testPrint {currentFilePath = @ "/ Users / oyvind / Desktop / _DSC8797.jpg";  [self sendFile: currentFilePath];  } - (void) sendFile: (NSString *) filePath {IOBluetoothOBEXSession * obexSession = [[IOBluetoothOBEXSession alloc] initWithSDPServiceRecord: serviceRecord];  if (obexSession! = nil) {NSLog (@ "OBEX Session Established");  OBEXFileTransferServices * fst = [OBEXFileTransferServices withOBEXSession: obexSession];  OBEXDelegate * obxd = [[OBEXDelegate alloc] init];  [obxd setFile: filePath];  [fst setDelegate: obxd];  OBEXError cnctResult = [fst connectToObjectPushService];  if (cnctResult! = kIOReturnSuccess) {NSLog (@ "Error creating connection");  return  } else {NSLog (@ "OBEX Session Created. Sending file:% @", filePath);  [fst sendFile: filePath];  [printer openConnection];  }} else {NSLog (@ "Error creating OBEX session");  NSLog (@ "Error sending file");  }} @end 
+4
source share
1 answer

OK this is what ultimately became the main part of the functionality. The application I made was a kind of print server for Polaroid instant printers that would only accept images through Object Push.

First, make sure that the observed folder exists.

/* Looks for a directory named PolaroidWatchFolder in the user desktop directory and creates it if it does not exist. */ - (void) ensureWatchedFolderExists { NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *url = [NSURL URLWithString:@"PolaroidWatchFolder" relativeToURL:[[fileManager URLsForDirectory:NSDesktopDirectory inDomains:NSUserDomainMask] objectAtIndex:0]]; BOOL isDir; if ([fileManager fileExistsAtPath:[url path] isDirectory:&isDir] && isDir) { [self log:[NSString stringWithFormat:@"Watched folder exists at %@", [url absoluteURL]]]; watchFolderPath = url; } else { NSError *theError = nil; if (![fileManager createDirectoryAtURL:url withIntermediateDirectories:NO attributes:nil error:&theError]) { [self log:[NSString stringWithFormat:@"Watched folder could not be created at %@", [url absoluteURL]]]; } else { watchFolderPath = url; [self log:[NSString stringWithFormat:@"Watched folder created at %@", [url absoluteURL]]]; } } } 

Then scan the available printers:

 /* Loops through all paired Bluetooth devices and retrieves OBEX Object Push service records for each device who name starts with "Polaroid". */ - (void) findPairedDevices { NSArray *pairedDevices = [IOBluetoothDevice pairedDevices]; devicesTested = [NSMutableArray arrayWithCapacity:0]; for (IOBluetoothDevice *device in pairedDevices) { if ([self deviceQualifiesForAddOrRenew:device.name]) { BluetoothPushDevice *pushDevice = [[BluetoothPushDevice new] initWithDevice:device]; if (pushDevice != nil) { [availableDevices addObject:pushDevice]; [pushDevice testConnection]; } } } } 

This last function call is associated with the built-in BluetoothPushDevice method to test the connection. Here is the delegate handler for the response:

 - (void) deviceStatusHandler: (NSNotification *)notification { BluetoothPushDevice *device = [notification object]; NSString *status = [[notification userInfo] objectForKey:@"message"]; if ([devicesTested count] < [availableDevices count] && ![devicesTested containsObject:device.name]) { [devicesTested addObject:device.name]; } } 

When the server starts, this method will be launched in response to a timer or manual scan:

 - (void) checkWatchedFolder { NSError *error = nil; NSArray *properties = [NSArray arrayWithObjects: NSURLLocalizedNameKey, NSURLCreationDateKey, NSURLLocalizedTypeDescriptionKey, nil]; NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:watchFolderPath includingPropertiesForKeys:properties options:(NSDirectoryEnumerationSkipsHiddenFiles) error:&error]; if (files == nil) { [self log:@"Error reading watched folder"]; return; } if ([files count] > 0) { int newFileCount = 0; for (NSURL *url in files) { if (![filesInTransit containsObject:[url path]]) { NSLog(@"New file: %@", [url lastPathComponent]); [self sendFile:[url path]]; newFileCount++; } } } } 

When new files are found, ww first you need to find a device that is not busy receiving its print file:

 /* Loops through all discovered device service records and returns the a new OBEX session for the first it finds that is not connected (meaning it is not currently in use, connections are ad-hoc per print). */ - (BluetoothPushDevice*) getIdleDevice { for (BluetoothPushDevice *device in availableDevices) { if ([device.status isEqualToString:kBluetoothDeviceStatusReady]) { return device; } } return nil; } 

Then the file is sent using this method:

 - (void) sendFile:(NSString *)filePath { BluetoothPushDevice *device = [self getIdleDevice]; if( device != nil ) { NSLog(@"%@ is available", device.name); if ([device sendFile:filePath]) { [self log:[NSString stringWithFormat:@"Sending file: %@", filePath]]; [filesInTransit addObject:filePath]; } else { [self log:[NSString stringWithFormat:@"Error sending file: %@", filePath]]; } } else { NSLog(@"No idle devices"); } } 

After the transfer is complete, this delegate method is called:

 /* Responds to BluetoothPushDevice TransferComplete notification */ - (void) transferStatusHandler: (NSNotification *) notification { NSString *status = [[notification userInfo] objectForKey:@"message"]; NSString *file = ((BluetoothPushDevice*)[notification object]).file; if ([status isEqualToString:kBluetoothTransferStatusComplete]) { if ([filesInTransit containsObject:file]) { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; [fileManager removeItemAtPath:file error:&error]; if (error != nil) { [self log:[NSString stringWithFormat:@"**ERROR** File %@ could not be deleted (%@)", file, error.description]]; } [self log:[NSString stringWithFormat:@"File deleted: %@", file]]; [filesInTransit removeObject:file]; } else { [self log:[NSString stringWithFormat:@"**ERROR** filesInTransit array does not contain file %@", file]]; } } [self updateDeviceStatusDisplay]; } 

Hope this helps someone!

+2
source

All Articles