Подтвердить что ты не робот

Отправить уведомление от javascript в UIWebView в ObjectiveC

Мне нужно знать, что нужно сделать, чтобы использовать JavaScript в HTML, сидящем в UIWebView, чтобы уведомить Objective-C, что что-то случилось?

Чтобы быть более точным, я играю некоторую анимацию JavaScript в HTML, и мне нужно предупредить код Objective-C, который закончилась анимацией.

4b9b3361

Ответ 1

Кажется, нет официального способа сделать это. Однако стандарт включает в себя чтение и анализ входящих запросов URL-адресов, в основном сворачивание собственного сериализованного протокола обмена сообщениями. Обработка сообщений должна выполняться в методе webView:shouldStartLoadWithRequest:navigationType вашего контроллера вида.

Примечание: существует несколько бесплатных библиотек (PhoneGap, QuickConnect, JS-to- Cocoa Bridge), которые обертывают эту функциональность (плюс делают намного больше), Чтобы изобрести колесо (или знать, почему это круто, так сказать), читайте дальше.

Из JavaScript вы вызовете обратный вызов, пытаясь перейти к новому URL-адресу:

// In JavaScript
window.location = 'myapp:myaction:param1:param2'; // etc...

В Objective-C выполните UIWebViewDelegate протокол в файле .h:

// In your header file
@interface MyAppViewController : UIViewController <UIWebViewDelegate> {
  ...
}
@end

Затем реализуем метод в вашем файле .m:

// In your implementation file
-(BOOL)webView:(UIWebView *)webView2
       shouldStartLoadWithRequest:(NSURLRequest *)request
       navigationType:(UIWebViewNavigationType)navigationType
{
  // Break apart request URL
  NSString *requestString = [[request URL] absoluteString];
  NSArray *components = [requestString componentsSeparatedByString:@":"];

  // Check for your protocol
  if ([components count] > 1 &&
      [(NSString *)[components objectAtIndex:0] isEqualToString:@"myapp"])
  {
    // Look for specific actions
    if ([(NSString *)[components objectAtIndex:1] isEqualToString:@"myaction"])
    {
      // Your parameters can be found at
      //   [components objectAtIndex:n]
      // where 'n' is the ordinal position of the colon-delimited parameter
    }

    // Return 'NO' to prevent navigation
    return NO;
  }

  // Return 'YES', navigate to requested URL as normal
  return YES;
}

Две важные заметки:

  • Контекст: переход к myapp:whatever будет (конечно) завершен в любом другом контексте. Имейте это в виду, если вы загружаете межплатформенные страницы.

  • Сроки: если второй вызов window.location = выполняется до первого возврата, он будет "потерян". Таким образом, объедините свои вызовы вместе, задержите выполнение вручную или реализуйте очередь, которая объединяет вышеперечисленное с JS-запросы в Objective-C объекты.

Ответ 2

Собственно, для синхронизации в iOS (возможно, не для OSX?), если второй вызов window.location выполняется до того, как выполняется предыдущий вызов window.location, тогда первый вызов window.location будет потерян. Я думаю, что вызов window.location выполняется асинхронно с JavaScript после его вызова, и если другой вызов выполняется до его выполнения, он отменяет первый.

Например, при захвате событий касания я видел, что ontouchstart не отправляется через window.location, если событие ontouchmove происходит быстро после этого (например, при быстром прокрутке пальца). Таким образом, ваш Objective-C не получает событие ontouchstart. Это скорее проблема на оригинальном iPad, чем iPad2, я полагаю, из-за скорости обработки.

Ответ 3

Ответ zourtney правильный, но забыл упомянуть одно: нужно было зарегистрировать делегата в webview на

- (void)viewDidLoad {
    [super viewDidLoad];  --- instantiate _webview next .. then 

    _webview.delegate = self;  //important .. needed to register webview to delegate
}

надеюсь, что это поможет.....

Ответ 4

Быстрая версия

class ViewController: UIViewController,UIWebViewDelegate{

    @IBOutlet weak var webviewInstance: UIWebView!
    override func viewDidLoad() {
        webviewInstance.delegate = self
        super.viewDidLoad()

    }


    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        let requestString: String = (request.URL?.absoluteString)!
        var components: [AnyObject] = requestString.componentsSeparatedByString(":")
        // Check for your protocol
        if components.count > 1 && (String(components[0]) == "myapp") {
            // Look for specific actions
            if (String(components[1]) == "myaction") {
                // Your parameters can be found at
                //   [components objectAtIndex:n]
            }
            return false
        }
        return true
    }
}