Skip to content

Commit

Permalink
added Native 10.8 UserNotifications
Browse files Browse the repository at this point in the history
  • Loading branch information
euforic committed Jul 26, 2012
1 parent ba931d3 commit 414df37
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 20 deletions.
6 changes: 6 additions & 0 deletions MacGap.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */ = {isa = PBXBuildFile; fileRef = 1495814E15C15CCC00E1CFE5 /* Notice.m */; };
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 88746BED14CCA435001E160E /* JSEventHelper.m */; };
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0645F14BDE10A00E4BCE2 /* Window.m */; };
88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 88C0646414BDEC5800E4BCE2 /* Window.xib */; };
Expand Down Expand Up @@ -46,6 +47,8 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
1495814D15C15CCC00E1CFE5 /* Notice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Notice.h; path = Classes/Commands/Notice.h; sourceTree = "<group>"; };
1495814E15C15CCC00E1CFE5 /* Notice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Notice.m; path = Classes/Commands/Notice.m; sourceTree = "<group>"; };
88746BEC14CCA435001E160E /* JSEventHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSEventHelper.h; path = Classes/JSEventHelper.h; sourceTree = "<group>"; };
88746BED14CCA435001E160E /* JSEventHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSEventHelper.m; path = Classes/JSEventHelper.m; sourceTree = "<group>"; };
88C0645E14BDE10A00E4BCE2 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Window.h; path = Classes/Window.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -122,6 +125,8 @@
FA3250E114BA87DD00BF0781 /* Commands */ = {
isa = PBXGroup;
children = (
1495814D15C15CCC00E1CFE5 /* Notice.h */,
1495814E15C15CCC00E1CFE5 /* Notice.m */,
FA3250CA14BA860800BF0781 /* Dock.h */,
FA3250CB14BA860800BF0781 /* Dock.m */,
FA3250BD14BA85E700BF0781 /* Utils.h */,
Expand Down Expand Up @@ -289,6 +294,7 @@
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */,
88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */,
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */,
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
20 changes: 20 additions & 0 deletions MacGap/Classes/Commands/Notice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Notice.h
// MacGap
//
// Created by Christian Sullivan on 7/26/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import <Foundation/Foundation.h>

#define APP_NOTICE_NOTIFICATION @"Notice"

@interface Notice : NSObject <NSUserNotificationCenterDelegate> {

}

- (void) notify:(NSDictionary*)message;

@end

50 changes: 50 additions & 0 deletions MacGap/Classes/Commands/Notice.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Notice.m
// MacGap
//
// Created by Christian Sullivan on 7/26/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import "Notice.h"

@implementation Notice

- (void) notify:(NSDictionary *)message {
NSUserNotification *notification = [[NSUserNotification alloc] init];
[notification setTitle:[message valueForKey:@"title"]];
[notification setInformativeText:[message valueForKey:@"content"]];
[notification setDeliveryDate:[NSDate dateWithTimeInterval:0 sinceDate:[NSDate date]]];
[notification setSoundName:NSUserNotificationDefaultSoundName];
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
[center scheduleNotification:notification];
}

#pragma mark WebScripting Protocol

+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
{
if (selector == @selector(notify:))
return NO;

return YES;
}

+ (NSString*) webScriptNameForSelector:(SEL)selector
{
id result = nil;

if (selector == @selector(notify:)) {
result = @"notify";
}

return result;
}

// right now exclude all properties (eg keys)
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
{
return YES;
}

@end
3 changes: 3 additions & 0 deletions MacGap/Classes/WebViewDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@class Sound;
@class Dock;
@class Growl;
@class Notice;
@class Path;
@class App;
@class Window;
Expand All @@ -14,6 +15,7 @@
Sound* sound;
Dock* dock;
Growl* growl;
Notice* notice;
Path* path;
App* app;
Window* window;
Expand All @@ -24,6 +26,7 @@
@property (nonatomic, retain) Sound* sound;
@property (nonatomic, retain) Dock* dock;
@property (nonatomic, retain) Growl* growl;
@property (nonatomic, retain) Notice* notice;
@property (nonatomic, retain) Path* path;
@property (nonatomic, retain) App* app;
@property (nonatomic, retain) Window* window;
Expand Down
3 changes: 3 additions & 0 deletions MacGap/Classes/WebViewDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#import "Sound.h"
#import "Dock.h"
#import "Growl.h"
#import "Notice.h"
#import "Path.h"
#import "App.h"
#import "Window.h"
Expand All @@ -11,6 +12,7 @@ @implementation WebViewDelegate
@synthesize sound;
@synthesize dock;
@synthesize growl;
@synthesize notice;
@synthesize path;
@synthesize app;
@synthesize window;
Expand All @@ -21,6 +23,7 @@ - (void) webView:(WebView*)webView didClearWindowObject:(WebScriptObject*)window
if (self.sound == nil) { self.sound = [Sound new]; }
if (self.dock == nil) { self.dock = [Dock new]; }
if (self.growl == nil) { self.growl = [Growl new]; }
if (self.notice == nil) { self.notice = [Notice new]; }
if (self.path == nil) { self.path = [Path new]; }

if (self.app == nil) {
Expand Down
48 changes: 28 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#MacGap

The MacGap project aims to provide HTML/JS/CSS developers an Xcode project for developing Native OSX Apps that run in OSX's WebView and take advantage of WebKit technologies. The project also exposes a basic JavaScript API for OS integration, such as display Growl notifications. The MacGap project is extremely lightweight and nimble, a blank application is about 0.3mb.
The MacGap project aims to provide HTML/JS/CSS developers an Xcode project for developing Native OSX Apps that run in OSX's WebView and take advantage of WebKit technologies. The project also exposes a basic JavaScript API for OS integration, such as display Growl notifications. The MacGap project is extremely lightweight and nimble, a blank application is about 0.3mb.

##Pre-requisites

MacGap works on OSX 10.6 and 10.5.

Generate apps with the [macgap generator](http://github.com/maccman/macgap-rb), no compile necessary.

gem install macgap
gem install macgap

macgap new myapp
macgap build myapp

##API

MacGap exposes an object called `macgap` inside JavaScript. You can use it to alter the Dock icon and display Growl notifications, amongst other things. The API is documented below:
Expand All @@ -24,22 +24,22 @@ App:

// Activate application (bring to front)
macgap.app.activate();

// Hide application
macgap.app.hide();

// Un-hide application
macgap.app.unhide();

// System bell
macgap.app.beep();

// Open URL in default browser
macgap.app.open("http://google.com");

// Launch application
macgap.app.launch("TextEdit");

Window:

// Open a new window
Expand All @@ -50,28 +50,28 @@ Window:

// Move window (Bottom left is x:0 and y:0)
macgap.window.move({x:0, y: 200});

Path:

// Path to application
macgap.path.application;

// Path to application's resources
macgap.path.resource;

Dock:

// Set the Dock's badge
macgap.dock.badge = "10";

Sound:

// Play a sound
macgap.sound.play("./my/sound.mp3")

// Play a system sound
macgap.sound.playSystem("funk");

Growl:

// Send a Growl notification
Expand All @@ -80,17 +80,25 @@ Growl:
content: "New Message!"
});

Notice:

// Send a Native User notification
macgap.notice.notify({
title: "Notify",
content: "New Message!"
});

Events:

//Mac OS X on wake event.
document.addEventListener('wake', function(){console.log('Wake!!')}, true);

//Mac OS X on sleep event.
document.addEventListener('sleep', function(){console.log('Sleep!!')}, true);

##Offline Patterns

Desktop apps load immediately and work offline, whilst web apps have the advantage of being easily updated and remotely managed. MacGap gives you the best of both worlds via HTML5's offline APIs.
Desktop apps load immediately and work offline, whilst web apps have the advantage of being easily updated and remotely managed. MacGap gives you the best of both worlds via HTML5's offline APIs.

First you can define a refresh tag in `index.html`, which will immediately forward your WebView to a given address.

Expand Down

0 comments on commit 414df37

Please sign in to comment.