Я работаю над доказательством концепции приложения, которое использует двустороннюю связь между Objective C (iOS 7) и JavaScript с использованием рамки WebKit JavaScriptCore. Я, наконец, смог заставить его работать, как ожидалось, но столкнулся с ситуацией, когда UIWebView теряет ссылку на объект iOS, который я создал через JSContext.UIWebView JavaScript, теряющий ссылку на пространство имен (объект) iOS JSContext
приложение является немного сложным, здесь основы:
- Я бегу веб-сервер на устройстве IOS (CocoaHTTPServer)
- UIWebView первоначально загружает удаленный URL, а позже перенаправляется обратно в
localhost
как часть потока приложения (думаю OAuth) - HTML-страница, на которую приложение хостов (на локальном хосте) имеет JavaScript, который должен быть разговор с моим кодом IOS
Вот сторона IOS, мой ViewController в .h
:
#import <UIKit/UIKit.h>
#import <JavaScriptCore/JavaScriptCore.h>
// These methods will be exposed to JS
@protocol DemoJSExports <JSExport>
-(void)jsLog:(NSString*)msg;
@end
@interface Demo : UIViewController <UserInfoJSExports, UIWebViewDelegate>
@property (nonatomic, readwrite, strong) JSContext *js;
@property (strong, nonatomic) IBOutlet UIWebView *webView;
@end
И соответствующие части .m
в ViewController в:
-(void)viewDidLoad {
[super viewDidLoad];
// Retrieve and initialize our JS context
NSLog(@"Initializing JavaScript context");
self.js = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// Provide an object for JS to access our exported methods by
self.js[@"ios"] = self;
// Additional UIWebView setup done here...
}
// Allow JavaScript to log to the Xcode console
-(void)jsLog(str) {
NSLog(@"JavaScript: %@", str);
}
Здесь вы (упрощены для этого вопроса) HTML/сторона JS:
<html>
<head>
<title>Demo</title>
<script type="text/javascript">
function setContent(c, noLog){
with(document){
open();
write('<p>' + c + '</p>');
close();
}
// Write content to Xcode console
noLog || ios.jsLog(c);
}
</script>
</head>
<body onload="javascript:setContent('ios is: ' + typeof ios)">
</body>
</html>
Теперь, почти во всех случаях это работает прекрасно, я вижу ios is: object
как в UIWebView и в кон Xcode в единственный. Очень круто. Но в одном конкретном случае, 100% времени, это терпит неудачу после определенного количества переадресаций в UIWebView, и после того, как выше страница, наконец загружает он говорит:
Иос: не определено
... и остальная часть логики JS завершается, потому что последующий вызов ios.jsLog
в функции setContent
приводит к неопределенному исключению объекта.
Итак, наконец, мой вопрос: что может/может привести к потере АОНтекта? Я вырыл «документацию» в файлах .h файлов JavaScriptCore и обнаружил, что единственный способ, которым это должно случиться, - это, если больше нет strong
ссылок на JSContext
, но в моем случае у меня есть один из моих собственных, так что Кажется правильным.
Моя единственная другая гипотеза состоит в том, что он должен делать с тем, как я приобретающего JSContext
ссылка:
self.js = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
Я знаю, что это не может быть официально поддерживается Apple, хотя я нашел хотя бы один SO'er, который сказал, что у него есть одобренное Apple приложение, которое использовало этот самый метод.
EDIT
Я должен упомянуть, я реализовал UIWebViewDelegate
проверить JSContext после каждого перенаправления в UIWebView таким образом:
-(void)webViewDidFinishLoad:(UIWebView *)view{
// Write to Xcode console via our JSContent - is it still valid?
[self.js evaluateScript:@"ios.jsLog('Can see JS from obj c');"];
}
Это работает во всех случаях, даже если веб-страница, наконец, загружает и сообщает ios is: undefined
вышеупомянутый метод одновременно записывает Can see JS from obj c
в консоль Xcode. Это, по-видимому, указывает на то, что JSContext по-прежнему действует, и по какой-то причине он просто больше не виден от JS.
Извиняюсь за очень многословно вопрос, есть так мало документации по этому вопросу, что там я понял, чем больше информации я мог бы предоставить, тем лучше.
Привет Madbreaks, у меня есть вопрос, связанный с общением между JS и IOS. Если у вас есть идея решить, сообщите мне. Ниже приведена ссылка «http://stackoverflow.com/questions/27120280/communication-between-javascript-and-objective-c-ios» – Mahesh