5

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

我现在可以生成蓝牙服务浏览器并选择设备及其 OBEX 服务,建立服务并创建连接,但随后什么也没有发生。谁能指出我的方向/向我展示一个可行的简单示例?

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

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    IOBluetoothServiceBrowserController *browser = [IOBluetoothServiceBrowserController serviceBrowserController:0];
    [浏览器运行模式];

    //IOBluetoothSDPServiceRecord
    IOBluetoothSDPServiceRecord *result = [[browser getResults] objectAtIndex:0];
    [自我描述:结果];

    if ([[result.device.name substringToIndex:8] isEqualToString:@"Polaroid"]) {
        打印机=结果.设备;
        服务记录 = 结果;
        [自测打印];
    }
    别的 {
        NSLog(@"%@ 不是一个有效的设备", result.device.name);
    }
}

-(无效)testPrint {
     currentFilePath = @"/Users/oyvind/Desktop/_DSC8797.jpg";
    [自我发送文件:当前文件路径];
}

- (void) sendFile:(NSString *)filePath {
    IOBluetoothOBEXSession *obexSession = [[IOBluetoothOBEXSession alloc] initWithSDPServiceRecord:serviceRecord];

    如果(obexSession!= 无)
    {
        NSLog(@"OBEX 会话建立");

        OBEXFileTransferServices *fst = [OBEXFileTransferServices with OBEXSession:obexSession];
        OBEXDelegate *obxd = [[OBEXDelegate alloc] init];
        [obxd setFile:filePath];
        [fst setDelegate:obxd];

        OBEXError cnctResult = [fst connectToObjectPushService];

        如果(cnctResult!= kIOReturnSuccess){
            NSLog(@"创建连接时出错");
            返回;
        }
        别的 {
            NSLog(@"OBEX 会话已创建。发送文件:%@", filePath);
            [fst sendFile:filePath];
            [打印机打开连接];
        }
    }
    别的 {
        NSLog(@"创建 OBEX 会话时出错");
        NSLog(@"发送文件出错");
    }
}

@结尾
4

1 回答 1

2

好的; 这就是最终成为功能核心部分的内容。我制作的应用程序是一种用于宝丽来即时打印机的打印服务器,它只接受对象推送上的图像。

首先,确保监视文件夹存在。

/*

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

在服务器启动时,此方法将运行以响应计时器滴答声或手动扫描:

- (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 首先需要找到一个不忙于接收打印文件的设备:

/*

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

我希望这可以帮助别人!

于 2013-07-30T10:07:15.927 回答