Skip to content

Commit

Permalink
More WIP to implement fake service worker
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesnvc committed Nov 1, 2018
1 parent 7a74141 commit b383555
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 14 deletions.
80 changes: 72 additions & 8 deletions src/ios/CDVServiceWorker.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
#import "CDVServiceWorker.h"

@interface CDVServiceWorker ()

@property (nonatomic,strong) NSOperationQueue *queue;
@property (nonatomic,strong) dispatch_semaphore_t workerReadySemaphore;
@property (nonatomic,strong) NSString *scriptUrl;
@property (nonatomic,strong) NSString *scope;

@end

@implementation CDVServiceWorker

- (void)pluginInitialize
{
NSLog(@"Initing service worker plugin");
self.workerReadySemaphore = dispatch_semaphore_create(0);
self.queue = [[NSOperationQueue alloc] init];
[self prepareJavascriptContext];
}

#pragma mark - Caching stuff

- (NSData*)requestFromCache:(id)request {
return nil;
}

#pragma mark - "Service Worker" context

typedef void(^JSPromiseCallback)(JSValue *resolve, JSValue *reject);

- (void)prepareJavascriptContext
{
self.jsContext = [[JSContext alloc] init];
Expand All @@ -18,47 +37,92 @@ - (void)prepareJavascriptContext
encoding:NSUTF8StringEncoding
error:nil];
[self.jsContext evaluateScript:shimScript];
self.jsContext[@"cache"][@"match"] = ^(id requestOrURL){
NSLog(@"SW: CHECKING FOR MATCH WITH %@", requestOrURL);
JSValue* promiseClass = self.jsContext[@"Promise"];
JSPromiseCallback cb = ^(JSValue* resolve, JSValue *reject) {
NSData *resp = [self requestFromCache:requestOrURL];
id arg;
if (resp == nil) {
arg = [NSNull null];
} else {
arg = resp;
}
[resolve callWithArguments:@[arg]];
};
JSValue *respPromise = [promiseClass constructWithArguments:@[cb]];
return respPromise;
};
self.jsContext[@"cache"][@"add"] = ^(id requestOrURL){
NSLog(@"SW: ADDING request %@", requestOrURL);
};
self.jsContext[@"cache"][@"put"] = ^(id requestOrURL, id response) {
NSLog(@"SW: PUTTING %@ for %@", response, requestOrURL);
};
}

#pragma mark - Methods called from javascript client

- (void)register:(CDVInvokedUrlCommand*)command
{
NSLog(@"Registering Service worker");
// TODO: check if a worker is already registered, signal error conditons
[self.commandDelegate runInBackground:^{
NSString *scriptUrl = [command argumentAtIndex:0];
self.scriptUrl = [command argumentAtIndex:0];
NSDictionary *options = [command argumentAtIndex:1];
NSString *scope = options[@"scope"];
self.scope = options[@"scope"];

NSURL *srcUrl = [[NSBundle mainBundle] URLForResource:scriptUrl withExtension:nil subdirectory:@"www"];
NSURL *srcUrl = [[NSBundle mainBundle] URLForResource:self.scriptUrl withExtension:nil subdirectory:@"www"];

NSLog(@"%@ scope %@ -> %@", scriptUrl, scope, srcUrl);
NSLog(@"%@ scope %@ -> %@", self.scriptUrl, self.scope, srcUrl);

NSString *script = [NSString stringWithContentsOfURL:srcUrl
encoding:NSUTF8StringEncoding
error:nil];
[self.jsContext evaluateScript:script];

[self.commandDelegate
sendPluginResult:[CDVPluginResult
resultWithStatus:CDVCommandStatus_OK
messageAsDictionary:@{@"installing": [NSNull null],
@"waiting": [NSNull null],
@"active": @{@"scriptURL": scriptUrl},
@"registeringScriptURL": scriptUrl,
@"scope": scope}]
@"active": @{@"scriptURL": self.scriptUrl},
@"registeringScriptURL": self.scriptUrl,
@"scope": self.scope}]
callbackId:command.callbackId];
dispatch_semaphore_signal(self.workerReadySemaphore);
}];
}

- (void)serviceWorkerReady:(CDVInvokedUrlCommand*)command
{
NSLog(@"Service worker ready");
[self.commandDelegate runInBackground:^{
dispatch_semaphore_wait(self.workerReadySemaphore, DISPATCH_TIME_FOREVER);

[self.commandDelegate
sendPluginResult:[CDVPluginResult
resultWithStatus:CDVCommandStatus_OK
messageAsDictionary:@{@"installing": [NSNull null],
@"waiting": [NSNull null],
@"active": @{@"scriptURL": self.scriptUrl},
@"registeringScriptURL": self.scriptUrl,
@"scope": self.scope}]
callbackId:command.callbackId];
}];
}

- (void)postMessage:(CDVInvokedUrlCommand*)command
{
NSLog(@"Posting message");
[self.commandDelegate runInBackground:^{
NSDictionary *event = @{@"data": [command argumentAtIndex:0],
@"ports": [command argumentAtIndex:1]};

JSValue* messageHandler = self.jsContext[@"self"][@"handlers"][@"message"];

[messageHandler callWithArguments:@[event]];
}];

}

@end
10 changes: 6 additions & 4 deletions src/ios/service_worker_shim.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
let self = {
self = {
skipWaiting: function() {},
clients: {claim: function() {}},
handlers: {},
Expand All @@ -7,11 +7,13 @@ let self = {
}
};

let caches = {
open: function(name) {
cache = {match: null, add: null, put: null};

caches = {
open: function(_name) {
return new Promise(function(resolve, reject) { resolve(cache); });
},
match: function(request) {

return cache.match(request);
}
};
3 changes: 1 addition & 2 deletions www/service_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ const exec = require('cordova/exec');
let ServiceWorker = function() { };

ServiceWorker.prototype.postMessage = function(message, transfers) {
exec(null, null, "ServiceWorker", "postMessage",
[JSON.stringify(message), transfers]);
exec(null, null, "ServiceWorker", "postMessage", [message, transfers]);
};

module.exports = ServiceWorker;

0 comments on commit b383555

Please sign in to comment.