わかった; 最終的に機能のコア部分になったのは次のとおりです。私が作成したアプリケーションは、オブジェクト プッシュ経由でのみ画像を受け入れるポラロイド インスタント プリンター用の一種のプリント サーバーでした。
まず、監視フォルダーが存在することを確認します。
/*
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];
}
これが誰かに役立つことを願っています!