একটি আইওএস ইউআইবিউব ভিউতে জাভাস্ক্রিপ্ট কনসোল.লগ ()


84

ইউআইউইউভিউ ভিউ দিয়ে আইফোন / আইপ্যাড অ্যাপ্লিকেশন লেখার সময়, কনসোলটি দৃশ্যমান নয়। এই দুর্দান্ত উত্তরটি দেখায় যে কীভাবে ত্রুটিগুলি ফাঁদ করা যায় তবে আমি কনসোল.লগ () পাশাপাশি ব্যবহার করতে চাই।


4
এটি প্রথমে ব্রাউজারে লিখুন, বিকাশকারী সরঞ্জাম চালু করুন, তারপরে কনসোল আউটপুটটি দেখুন।
বেটগ্যামিট

উত্তর:


185

একজন সম্মানিত সহকর্মীর সাথে পরামর্শের পরে আজ তিনি আমাকে সাফারি বিকাশকারী সরঞ্জামদণ্ডে সতর্ক করেছিলেন এবং এটি কীভাবে কনসোল আউটপুট (এবং ডিবাগিং!) এর জন্য আইওএস সিমুলেটারে ইউআইউইউবভিউসের সাথে সংযুক্ত হতে পারে।

পদক্ষেপ:

  1. সাফারি পছন্দগুলি খুলুন -> "উন্নত" ট্যাব -> চেকবক্সটি সক্ষম করুন "মেনু বারে বিকাশ মেনু দেখান"
  2. আইওএস সিমুলেটারে ইউআইবিউব ভিউ দিয়ে অ্যাপ্লিকেশন শুরু করুন
  3. সাফারি -> বিকাশ -> i (প্যাড / পড) সিমুলেটর -> [the name of your UIWebView file]

আপনি এখন জটিল (আমার ক্ষেত্রে, ফ্লোট ) জাভাস্ক্রিপ্ট এবং অন্যান্য স্টাফগুলিকে ইউআইউইউভিউভিউতে ফেলে দিতে পারেন এবং ইচ্ছামত ডিবাগ করতে পারেন।

সম্পাদনা: @ জোশুয়া জে ম্যাককিনন উল্লেখ করেছেন যে কোনও ডিভাইসে ইউআইওউবভিউগুলি ডিবাগ করার সময় এই কৌশলটিও কার্যকর হয়। কেবলমাত্র আপনার ডিভাইস সেটিংসে ওয়েব পরিদর্শককে সক্ষম করুন: সেটিংস-> সাফারি-> অ্যাডভান্সড-> ওয়েব ইন্সপেক্টর (চিয়ার্স @ জেরেমি উইবে)

আপডেট: ডাব্লুউইউব ভিউও সমর্থিত


13
দ্রষ্টব্য, বাস্তব কৌশল ডিভাইসগুলি ডিবাগ করার সময় এই কৌশলটিও কার্যকর করে works
জোশুয়া জে ম্যাককিনন

4
আমি পারলে +100। এটি দুর্দান্ত, এটি ফোন ফাঁক অ্যাপ্লিকেশনগুলির জন্যও কাজ করে!
অ্যান্ডি নোভোকিন

4
একটি আইপ্যাড দিয়ে চেষ্টা করছি, যখন আমি সাফারিতে ডেভেলপ মেনুতে যাই, বেছে নেওয়ার মতো কোনও ডিভাইস নেই। আমি যখন সিমুলেটরটিতে স্থাপন করি তখন এটি কবজির মতো কাজ করে।
ফ্লয়েডিয়ান

10
@ ফ্লয়েডিয়ান আপনাকে ডিভাইসে ওয়েব পরিদর্শক সক্ষম করতে হবে। সেটিংস-> সাফারি-> অ্যাডভান্সড-> ওয়েব ইন্সপেক্টর।
জেরেমি ওয়েইব

4
আমার অ্যাপ্লিকেশনটি আমার বিকাশ মেনুতে প্রদর্শিত হচ্ছে না। আমি ওয়েব ইন্সপেক্টরকে সক্ষম করেছি। সাফারি দেখায়, তবে আমার অ্যাপটি (যা বর্তমান; 2 টি ইউআইবিউজভিউ প্রদর্শন করছে) সনাক্ত করা যায়নি .. কোনও ধারণা?
নারকো

82

অ্যাপ্লিকেশন ডিবাগ কনসোলটিতে জাভাস্ক্রিপ্ট ব্যবহার করে লগ করার আমার একটি সমাধান রয়েছে। এটি কিছুটা অশোধিত, তবে এটি কার্যকর।

প্রথমত, আমরা জাভাস্ক্রিপ্টে কনসোল.লগ () ফাংশনটি সংজ্ঞায়িত করি, যা আইওস-লগ: ইউআরএল সহ একটি আইফ্রেমে খোলে এবং তত্ক্ষণাত সরিয়ে দেয়।

// Debug
console = new Object();
console.log = function(log) {
  var iframe = document.createElement("IFRAME");
  iframe.setAttribute("src", "ios-log:#iOS#" + log);
  document.documentElement.appendChild(iframe);
  iframe.parentNode.removeChild(iframe);
  iframe = null;    
};
console.debug = console.log;
console.info = console.log;
console.warn = console.log;
console.error = console.log;

এখন আমাদের এই ইউআরএলটি আইওএস অ্যাপ্লিকেশন UIWebViewDelegate- এ shouldstartLoadWithRequest ফাংশনটি ব্যবহার করতে হবে।

- (BOOL)webView:(UIWebView *)webView2 
shouldStartLoadWithRequest:(NSURLRequest *)request 
 navigationType:(UIWebViewNavigationType)navigationType {

    NSString *requestString = [[[request URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
    //NSLog(requestString);

    if ([requestString hasPrefix:@"ios-log:"]) {
        NSString* logString = [[requestString componentsSeparatedByString:@":#iOS#"] objectAtIndex:1];
                               NSLog(@"UIWebView console: %@", logString);
        return NO;
    }

    return YES;
}

4
নীচে এনএসটিজে-এর সহজ ধারণাটি দেখুন।
আশ্বিন এস


35

এই সুইফট সমাধানটি: (প্রসঙ্গটি পেতে এটি হ্যাকের কিছুটা)

  1. আপনি ইউআইবিউবভিউ তৈরি করেন।

  2. অভ্যন্তরীণ প্রসঙ্গটি পান এবং কনসোল.লগ () জাভাস্ক্রিপ্ট ফাংশন ওভাররাইড করুন ।

    self.webView = UIWebView()
    self.webView.delegate = self
    
    let context = self.webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext
    
    let logFunction : @convention(block) (String) -> Void =
    {
        (msg: String) in
    
        NSLog("Console: %@", msg)
    }
    context.objectForKeyedSubscript("console").setObject(unsafeBitCast(logFunction, AnyObject.self), 
                                                         forKeyedSubscript: "log")
    

4
+100! আমাকে অনেক সময় বাঁচিয়েছে, দুর্দান্ত হ্যাক করেছে, জেএস কোডে 0 টি পরিবর্তন দরকার। ধন্যবাদ !! ভবিষ্যতের পাঠকদের জন্য কেবল আমার 2 সেন্ট: JavaScriptCoreআপনার প্রকল্পের ফ্রেমওয়ার্ক এবং importএটি আপনার ওয়েবভিউ সুইচ ফাইলটিতে লিঙ্ক করতে ভুলবেন না ।
মাইন্ডবম্ব

। সুইফট 4 আমার জন্য কাজ করে ... আপনি NSString..context.objectForKeyedSubscript ( "কনসোল") setObject থেকে "লগ" কাস্ট haveto (: AnyObject.self), forKeyedSubscript: unsafeBitCast (logFunction, এর NSString হিসাবে "লগ")
সার্জ

28

IOS7 থেকে শুরু করে আপনি নেটিভ জাভাস্ক্রিপ্ট ব্রিজ ব্যবহার করতে পারেন। নিম্নলিখিত হিসাবে সহজ কিছু

 #import <JavaScriptCore/JavaScriptCore.h>

JSContext *ctx = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"console"][@"log"] = ^(JSValue * msg) {
NSLog(@"JavaScript %@ log message: %@", [JSContext currentContext], msg);
    };

আগ্রহের বাইরে, এই কোডটি রাখার আদর্শ জায়গা কোথায়?
লেসলি গডউইন

ঠিক আছে, এটি আউট। আপনি তৈরি করার ঠিক পরে আপনি UIWebviewকোনও JSContextস্টাফ সেটআপ করতে পারবেন ।
লেসলি গডউইন

4
না JSContextএখনও সঙ্গে আইওএস কাজ 8+ WKWebView?
নিকোলাই সামতেলজে

আমি এটি putোকানো - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationTypeএবং এটি পুরোপুরি কাজ করে!
আর্টুর বার্টজাক

@ নিকোলাইস্যামটেলডজে: আমি WKWebViewএবং আইওএস 11.4.1 দিয়ে চেষ্টা করেছি এবং সে খুঁজে পেয়ে documentViewক্র্যাশ করতে পারে না । আমি এই উত্তরটি দেখেছি এবং মনে হয় যে, এটি এইভাবে সম্ভব নয়।
পরীক্ষার

10

ইউটিউইভভিউ থেকে উদ্দেশ্য-সি তে যোগাযোগের জন্য নেটিভব্রিজ খুব সহায়ক। আপনি এটি কনসোল লগগুলি পাস করতে এবং উদ্দেশ্য-সি ফাংশনগুলিতে কল করতে পারেন।

https://github.com/ochameau/NativeBridge

console = new Object();
console.log = function(log) {
    NativeBridge.call("logToConsole", [log]);
};
console.debug = console.log;
console.info = console.log;
console.warn = console.log;
console.error = console.log;

window.onerror = function(error, url, line) {
    console.log('ERROR: '+error+' URL:'+url+' L:'+line);
};

এই কৌশলটির সুবিধা হ'ল লগ বার্তায় নতুন লাইনের মতো জিনিসগুলি সংরক্ষণ করা হয়।


+1 অ্যাপাচি কর্ডোভা ব্যবহারকারীদের জন্য নোট - কর্ডোভা ইতিমধ্যে পরিচালনা করে console.logতবে window.onerrorএই উত্তরের কাজটি খুব কার্যকর!
এমপন্টিলো

এক্সিলারেটর / টাইটানিয়াম বিকাশকারীদের জন্য: এটিও আপনার টিআইউআই.উইউব ভিউ
বাইটার্স

0

লেসলি গডউইনের ফিক্স চেষ্টা করেও এই ত্রুটিটি পেয়ে যাচ্ছিল:

'objectForKeyedSubscript' is unavailable: use subscripting

সুইফট ২.২-এর জন্য, এখানে আমার জন্য কী কাজ করেছে:

এই কোডটি সংকলনের জন্য আপনাকে জাভাস্ক্রিপ্ট কোর আমদানি করতে হবে:

import JavaScriptCore

if let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") {
    context.evaluateScript("var console = { log: function(message) { _consoleLog(message) } }")
    let consoleLog: @convention(block) String -> Void = { message in
        print("javascript_log: " + message)
    }
    context.setObject(unsafeBitCast(consoleLog, AnyObject.self), forKeyedSubscript: "_consoleLog")
}

তারপরে আপনার জাভাস্ক্রিপ্ট কোডে, কনসোল.লগকে কল করা ("_ আপনার_লগ_") এক্সকোড কনসোলে মুদ্রণ করবে।

আরও ভাল, এই কোডটি ইউআইবিউবভিউতে এক্সটেনশন হিসাবে যুক্ত করুন:

import JavaScriptCore

extension UIWebView {
    public func hijackConsoleLog() {
        if let context = valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") {
            context.evaluateScript("var console = { log: function(message) { _consoleLog(message) } }")
            let consoleLog: @convention(block) String -> Void = { message in
                print("javascript_log: " + message)
            }
            context.setObject(unsafeBitCast(consoleLog, AnyObject.self), forKeyedSubscript: "_consoleLog")
        }
    }
}

এবং তারপরে আপনার ইউআইবিউবিভিউ সূচনা পর্বের সময় এই পদ্ধতিটি কল করুন:

let webView = UIWebView(frame: CGRectZero)
webView.hijackConsoleLog()

0

সুইফট 5

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
      webView.evaluateJavaScript("your javascript string") { (value, error) in
          if let errorMessage = (error! as NSError).userInfo["WKJavaScriptExceptionMessage"] as? String {
                print(errorMessage)
          }
      }
 }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.