2012-08-01 51 views
4

我已经花了两天的时间搜索并阅读蓝牙编程指南,同时试图拼凑一个小型Mac应用程序,它将从下拉文件夹中检索图像,并通过蓝牙将任何新文件发送到预定设备。似乎没有很多好的例子可用。Mac到蓝牙设备的文件传输,简单的例子?

我正好能够产生蓝牙服务浏览器,并选择设备及其OBEX服务,建立服务并创建连接,但没有发生任何事情。任何人都可以请我指出/向我展示一个可行的简单例子吗?

附上AppDelegate源代码。谢谢阅读!

 
#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 
+0

有没有取得进展呢? – shein 2013-07-25 07:01:30

+0

是的。我最终得到它的工作,但它是一年前,我没有在我的头atm的细节。我可能应该更新线程。我会看看我能否在这个周末找到时间。 – nordhagen 2013-07-26 07:58:39

+0

将不胜感激! – shein 2013-07-28 14:08:46

回答

2

OK;这是最终成为功能的核心部分。我制作的应用程序是Polaroid即时打印机的打印服务器,它只接受Object Push上的图像。

首先,确保观看的文件夹存在。

/* 

    Looks for a directory named PolaroidWatchFolder in the user's 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]]]; 
     } 
    } 
} 

然后扫描可用打印机:

/* 

    Loops through all paired Bluetooth devices and retrieves OBEX Object Push service records 
    for each device who's 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];     
      } 
     } 
    } 
} 

这最后函数调用到BluetoothPushDevice内置的方法来测试连接。下面是响应委托处理程序:

- (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++; 
      } 
     } 
    } 
} 

当有新的文件被发现,WW首先需要:

- (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]; 
    } 
} 

在服务器启动时,该方法将在响应计时器滴答声或手动扫描运行找到一个设备不忙recieving打印它的一个文件:

/* 

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; 
} 

然后文件被用这种方法发送:

- (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"); 
    } 
} 

在转移完成后,此委托方法被称为:

/* 

    Responds to BluetoothPushDevice's 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]; 
} 

我希望这可以帮助别人!

+0

嗨Nordagen,你能否为这个项目提供你的其他课程?我需要和我的办公室一样的东西,并且找不到关于如何在Mac OS中将文件发送到蓝牙打印机的教程。 – Jukurrpa 2014-03-19 15:00:36

+0

对不起,我会尽我所能,但我不能随意分享。这是我以前的一份工作为客户完成的工作。然而,这里介绍的代码应该为您提供执行文件传输位所需的基本机制。 – nordhagen 2014-03-21 08:19:34

+0

没问题,同时我找到了一个可以重用的工作示例。 – Jukurrpa 2014-03-21 09:31:16