Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
psugihara committed Feb 8, 2011
0 parents commit b0ee133
Show file tree
Hide file tree
Showing 24 changed files with 9,618 additions and 0 deletions.
Binary file added FileWatcherExample/.DS_Store
Binary file not shown.
33 changes: 33 additions & 0 deletions FileWatcherExample/Classes/FileWatcher.h
@@ -0,0 +1,33 @@
//
// FileWatcher.h
// GitSync
//
// Abstract: FileWatcher watches for changes on a set of files and calls fileDidChangeAtPath.
//
// Created by Peter Sugihara on 1/4/11.
// Copyright 2011 Peter Sugihara. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol FileWatcherDelegate;
@interface FileWatcher : NSObject <NSCoding> {
@private
NSMutableDictionary *fileModificationDates; // Keys are bookmarks being watched.
id <FileWatcherDelegate> delegate;
NSRunLoop *runLoop;
NSFileManager *fm;
}

- (void)watchFileAtURL:(NSURL *)path;
- (void)stopWatchingFileAtURL:(NSURL *)path;

@property (nonatomic, assign) id <FileWatcherDelegate> delegate;
@property (nonatomic, retain) NSMutableDictionary *fileModificationDates;

@end


@protocol FileWatcherDelegate <NSObject>
- (void)fileDidChangeAtURL:(NSURL *)notification;
@end
118 changes: 118 additions & 0 deletions FileWatcherExample/Classes/FileWatcher.m
@@ -0,0 +1,118 @@
//
// FileWatcher.m
// GitSync
//
// Created by Peter Sugihara on 1/4/11.
// Copyright 2011 Peter Sugihara. All rights reserved.
//

#import "FileWatcher.h"

@interface FileWatcher()
- (void)startWatching;
- (void)checkForUpdates;
- (NSDate *)modificationDateForURL:(NSURL *)url;
- (NSURL *)urlFromBookmark:(NSData *)bookmark;
- (NSData *)bookmarkFromURL:(NSURL *)url;

@end


@implementation FileWatcher
@synthesize delegate;
@synthesize fileModificationDates;

- (id)init {
if ((self = [super init])) {
fm = [[NSFileManager alloc] init];
fileModificationDates = [[NSMutableDictionary alloc] init];
[self startWatching];
}

return self;
}

- (void)watchFileAtURL:(NSURL *)url {
NSData *bookmark = [self bookmarkFromURL:url];
NSDate *modDate = [self modificationDateForURL:url];

[fileModificationDates setObject:modDate forKey:bookmark];
}

- (void)stopWatchingFileAtURL:(NSURL *)url {
for (NSURL *watchedURL in [fileModificationDates allKeys]) {
if ([watchedURL isEqual:url])
[fileModificationDates removeObjectForKey:url];
}
}

- (NSDate *)modificationDateForURL:(NSURL *)URL {
NSDictionary *fileAttributes = [fm attributesOfItemAtPath:[URL path] error:NULL];
NSDate *modDate = [fileAttributes fileModificationDate];
return modDate;
}

- (void)startWatching {
int latency = 3;
NSTimer *timer = [NSTimer timerWithTimeInterval:latency
target:self
selector:@selector(checkForUpdates)
userInfo:nil
repeats:YES];
runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
}

- (void)checkForUpdates {
for (NSData *bookmark in [fileModificationDates allKeys]) {
NSURL *watchedURL = [self urlFromBookmark:bookmark];
NSDate *modDate = [self modificationDateForURL:watchedURL];
// Fires YES the first time it's called after the program turns on.
// Not sure why, don't really care right now. [Sorry !];
if ([modDate compare:[fileModificationDates objectForKey:bookmark
]] == NSOrderedDescending) {
[fileModificationDates setObject:modDate forKey:bookmark]; // update modDate
[delegate fileDidChangeAtURL:watchedURL]; // callback
}
}
}

- (NSData *)bookmarkFromURL:(NSURL *)url {
NSData *bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
includingResourceValuesForKeys:NULL
relativeToURL:NULL
error:NULL];
return bookmark;
}

- (NSURL *)urlFromBookmark:(NSData *)bookmark {
NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark
options:NSURLBookmarkResolutionWithoutUI
relativeToURL:NULL
bookmarkDataIsStale:NO
error:NULL];
return url;
}

- (void)dealloc {
// Clean-up code here.
[super dealloc];
}

#pragma mark -
#pragma mark NSCoding

- (id)initWithCoder:(NSCoder *)decoder {
if ((self = [self init])) {
NSDictionary *decoded = [decoder decodeObjectForKey:@"fileModificationDates"];
[fileModificationDates setDictionary:decoded];
}

return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:fileModificationDates forKey:@"fileModificationDates"];
}

@end
20 changes: 20 additions & 0 deletions FileWatcherExample/Classes/FileWatcherExampleAppDelegate.h
@@ -0,0 +1,20 @@
//
// FileWatcherExampleAppDelegate.h
// FileWatcherExample
//
// Created by Peter Sugihara on 2/8/11.
// Copyright 2011 Bard College. All rights reserved.
//

#import <Cocoa/Cocoa.h>
#import "FileWatcher.h"

@interface FileWatcherExampleAppDelegate : NSObject <NSApplicationDelegate, FileWatcherDelegate> {
FileWatcher *watcher;
}

- (void)fileDidChangeAtURL:(NSURL *)url;
- (void)watchFileAtURL:(NSURL *)url;
- (void)stopWatchingFileAtURL:(NSURL *)url;

@end
34 changes: 34 additions & 0 deletions FileWatcherExample/Classes/FileWatcherExampleAppDelegate.m
@@ -0,0 +1,34 @@
//
// FileWatcherExampleAppDelegate.m
// FileWatcherExample
//
// Created by Peter Sugihara on 2/8/11.
// Copyright 2011 Bard College. All rights reserved.
//

#import "FileWatcherExampleAppDelegate.h"

@implementation FileWatcherExampleAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
watcher = [[FileWatcher alloc] init];
watcher.delegate = self;

// A test watch:
// [self watchFileAtURL:[NSURL URLWithString:@"path/to/file"]];
}

- (void)fileDidChangeAtURL:(NSURL *)url {
NSLog(@"i saw that, %@!", url);
}

- (void)watchFileAtURL:(NSURL *)url {
[watcher watchFileAtURL:url];
}

- (void)stopWatchingFileAtURL:(NSURL *)url {
[watcher stopWatchingFileAtURL:url];
}


@end
34 changes: 34 additions & 0 deletions FileWatcherExample/FileWatcherExample-Info.plist
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

<key>CFBundleIdentifier</key>
<string>edu.pys.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

7 changes: 7 additions & 0 deletions FileWatcherExample/FileWatcherExample-Prefix.pch
@@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'FileWatcherExample' target in the 'FileWatcherExample' project
//

#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
13 changes: 13 additions & 0 deletions FileWatcherExample/FileWatcherExample-main.m
@@ -0,0 +1,13 @@
//
// FileWatcherExample-main.m
// FileWatcherExample
//
// Created by Peter Sugihara on 2/8/11.
// Copyright 2011 Bard College. All rights reserved.
//

#import <Cocoa/Cocoa.h>

int main(int argc, char *argv[]) {
return NSApplicationMain(argc, (const char **) argv);
}

0 comments on commit b0ee133

Please sign in to comment.