2010-05-29 36 views
8

Tôi đang cố chuyển nhiều thứ từ một trang web bên trong UIWebView trở lại ứng dụng iPhone của tôi thông qua phương thức shouldStartLoadWithRequest của UIWebView.Kích hoạt shouldStartLoadWithRequest với nhiều window.location.href gọi

Về cơ bản, cuộc gọi trang web của tôi window.location.href = "command: // foo = bar" và tôi có thể chặn điều đó trong ứng dụng của tôi không thành vấn đề. Bây giờ nếu tôi tạo một vòng lặp và thực hiện nhiều lệnh gọi window.location.href cùng một lúc, thì shouldStartLoadWithRequest chỉ xuất hiện để được gọi một lần và cuộc gọi nó nhận được là lần cuối cùng của window.location.href ở cuối vòng lặp.

Điều tương tự cũng xảy ra với chế độ xem web dành cho Android, chỉ cửa sổ window.location.href mới được xử lý.

+0

Tôi tìm thấy giải pháp thông minh. Tự động tạo một khung nội tuyến cho mỗi lệnh và đặt src của nó thành "command: // foo = bar", bạn có thể kích hoạt tính năng này nhiều lần trong một vòng lặp và shouldStartLoadWithRequest được gọi mỗi lần! Bây giờ hãy nghiên cứu cách tối ưu hóa điều này. Tôi không nghĩ rằng nó sẽ là tốt để tạo ra hàng ngàn iframe (mặc dù chúng được ẩn). Bất kỳ đề xuất về điều đó? – AlBeebe

+0

Tôi cũng sẽ cố gắng tối ưu hóa mọi cuộc gọi vị trí. Nếu bạn chỉ có thể gửi 60 cuộc gọi nói một phút, hãy đảm bảo rằng bạn đang gây nhiễu mọi cuộc gọi với đủ các vars truy vấn và các đoạn để xử lý nhiều lệnh cho mỗi cuộc gọi. Ngoài ra, bạn có thể muốn kiểm tra wkWebView: http://nshipster.com/wkwebkit/ nó tự động hóa nhiều quá trình này và đáng tin cậy hơn. – newshorts

Trả lời

39
iFrame = document.createElement("IFRAME"); 
iFrame.setAttribute("src", "command://foo=bar"); 
document.body.appendChild(iFrame); 
iFrame.parentNode.removeChild(iFrame); 
iFrame = null; 

Vì vậy, điều này tạo ra một khung nội tuyến, bộ nguồn của mình cho một im lệnh cố gắng để vượt qua các ứng dụng, sau đó càng sớm càng nối của nó đến shouldStartLoadWithRequest cơ thể được gọi, sau đó chúng tôi loại bỏ các iframe ra khỏi cơ thể, và đặt nó thành null để giải phóng bộ nhớ.

Tôi cũng đã thử nghiệm điều này trên chế độ xem web trên Android bằng cách sử dụng shouldOverrideUrlLoading và nó cũng hoạt động bình thường!

+3

Giải pháp này rất xấu xí, nhưng nó có vẻ là giải pháp ít xấu xí nhất có thể. Có vẻ như Javascript "tối ưu hóa" bằng cách bỏ qua các lệnh gọi window.location sau đó được thay thế bằng các lệnh gọi window.location khác. Cảm ơn bạn đã cứu tôi từ một phiên gỡ lỗi rất đau đớn! – Arkaaito

+0

@Arkaaito +1 vì xấu xí, tôi hoàn toàn đồng ý – AlBeebe

+4

Tôi muốn theo dõi kể từ khi tôi đăng bài này 2 năm trước. Tôi đã viết một ứng dụng Android và iPhone về cơ bản là một webview được bao bọc trong một ứng dụng gốc. Tôi đã sử dụng giải pháp này để tôi có thể giao tiếp từ webview đến ứng dụng gốc và nó hoạt động hoàn hảo trong 2 năm qua tôi đã có hơn 500 nghìn lượt tải xuống ứng dụng của mình. – AlBeebe

0

Không, thay đổi url của khung nội tuyến sẽ không kích hoạt shouldOverrideUrlLoading, ít nhất là không có trong Android 2.2.

3

Tôi cũng đã xảy ra sự cố này và đây là giải pháp của tôi phù hợp với tôi. Tất cả các hàm JavaScript của tôi sử dụng hàm này __js2oc (msg) để chuyển dữ liệu và các sự kiện đến Objective-C qua shouldStartLoadWithRequest: P.S. thay thế "command:" bằng trình kích hoạt "appname:" mà bạn sử dụng.

/* iPhone JS2Objective-C bridge interface */ 
var __js2oc_wait = 300; // min delay between calls in milliseconds 
var __prev_t = 0; 
function __js2oc(m) { 
    // It's a VERY NARROW Bridge so traffic must be throttled 
    var __now = new Date(); 
    var __curr_t = __now.getTime(); 
    var __diff_t = __curr_t - __prev_t; 
    if (__diff_t > __js2oc_wait) { 
    __prev_t = __curr_t; 
    window.location.href = "command:" + m; 
    } else { 
    __prev_t = __curr_t + __js2oc_wait - __diff_t; 
    setTimeout(function() { 
     window.location.href = "command:" + m; 
    }, (__js2oc_wait - __diff_t)); 
    } 
} 
Các vấn đề liên quan