-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WKWebView Support #27
Comments
+1 here. The performance gains are pretty incredible, and apps for iOS8 forward are going to increasingly use it. |
@tomerlevi444: I'm not using this in production as much as I was, so I haven't been adding new features. If you submit a PR, I'm happy to merge it. |
@tcoulter, upon further research, |
This works fine: In JockeyWK.h #import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
@interface JockeyWK : NSObject
typedef void (^ JockeyWKHandler)(NSDictionary *payload);
typedef void (^ JockeyWKAsyncHandler)(WKWebView *webView, NSDictionary *payload, void (^complete)());
+ (void)on:(NSString*)type perform:(JockeyWKHandler)handler;
+ (void)on:(NSString*)type performAsync:(JockeyWKAsyncHandler)handler;
+ (void)send:(NSString*)type withPayload:(id)payload toWebView:(WKWebView*)webView;
+ (BOOL)webView:(WKWebView*)webView withUrl:(NSURL*)url;
@property (strong, atomic) NSNumber *messageCount;
@property (strong, nonatomic) NSMutableDictionary *listeners;
@property (strong, nonatomic) NSMutableDictionary *callbacks;
@end In JockeyWK.m #import "JockeyWK.h"
@implementation JockeyWK
+ (id)sharedInstance
{
static dispatch_once_t once;
static JockeyWK *sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
sharedInstance.messageCount = @0;
sharedInstance.listeners = [[NSMutableDictionary alloc] init];
sharedInstance.callbacks = [[NSMutableDictionary alloc] init];
});
return sharedInstance;
}
+ (void)on:(NSString*)type perform:(JockeyWKHandler)handler {
void (^ extended)(WKWebView *webView, NSDictionary *payload, void (^ complete)()) = ^(WKWebView *webView, NSDictionary *payload, void(^ complete)()) {
handler(payload);
complete();
};
[self on:type performAsync:extended];
}
+ (void)on:(NSString *)type performAsync:(JockeyWKAsyncHandler)handler
{
JockeyWK *instance = [JockeyWK sharedInstance];
NSDictionary *listeners = [instance listeners];
NSMutableArray *listenerList = [listeners objectForKey:type];
if (listenerList == nil) {
listenerList = [[NSMutableArray alloc] init];
[instance.listeners setValue:listenerList forKey:type];
}
[listenerList addObject:handler];
}
+ (void)send:(NSString*)type withPayload:(id)payload toWebView:(WKWebView*)webView {
JockeyWK *jockey = [JockeyWK sharedInstance];
NSNumber *messageId = jockey.messageCount;
NSError *err;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload options:NSJSONWritingPrettyPrinted error:&err];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *javascript = [NSString stringWithFormat:@"Jockey.trigger(\"%@\", %i, %@);", type, (int)[messageId integerValue], jsonString];
[webView evaluateJavaScript:javascript completionHandler:nil];
jockey.messageCount = @([jockey.messageCount integerValue] + 1);
}
+ (BOOL)webView:(WKWebView*)webView withUrl:(NSURL*)url
{
if ( [[url scheme] isEqualToString:@"jockey"] )
{
NSString *eventType = [url host];
NSString *messageId = [[url path] substringFromIndex:1];
NSString *query = [url query];
NSString *jsonString = [query stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData: [jsonString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
if ([eventType isEqualToString:@"event"]) {
[[self sharedInstance] triggerEventFromWebView:webView withData:JSON];
} else if ([eventType isEqualToString:@"callback"]) {
[[self sharedInstance] triggerCallbackForMessage:@([messageId integerValue])];
}
return NO;
}
return YES;
}
# pragma mark - Private methods
- (void)triggerCallbackForMessage:(NSNumber *)messageId {
NSString *messageIdString = [messageId stringValue];
void (^ callback)() = [_callbacks objectForKey:messageIdString];
if (callback != nil) {
callback();
}
[_callbacks removeObjectForKey:messageIdString];
}
- (void)triggerCallbackOnWebView:(WKWebView*)webView forMessage:(NSString*)messageId
{
NSString *javascript = [NSString stringWithFormat:@"Jockey.triggerCallback(\"%@\");", messageId];
[webView evaluateJavaScript:javascript completionHandler:nil];
}
- (void)triggerEventFromWebView:(WKWebView*)webView withData:(NSDictionary*)envelope
{
NSDictionary *listeners = [[JockeyWK sharedInstance] listeners];
NSString *messageId = [envelope objectForKey:@"id"];
NSString *type = [envelope objectForKey:@"type"];
NSDictionary *payload = [envelope objectForKey:@"payload"];
NSArray *listenerList = (NSArray*)[listeners objectForKey: type];
__block NSInteger executedCount = 0;
void (^complete)() = ^() {
executedCount += 1;
if (executedCount >= [listenerList count]) {
[[JockeyWK sharedInstance] triggerCallbackOnWebView: webView forMessage: messageId];
}
};
for (JockeyWKAsyncHandler handler in listenerList) {
handler(webView, payload, complete);
}
}
@end and just interact with it the same way you'd interact with Jockey usually. I don't know the exact version of Jockey I'm interacting with tho. From 2013 at least. |
Are there any plans on supporting iOS8's WKWebView?
The text was updated successfully, but these errors were encountered: