2012-04-18 4 views
9

これで時間がある。コンソール経由でJavaScriptからObj-Cコードを呼び出す:引数が削除されますか?

私はWebView、WebScripting API、およびそのAPIで定義された単一のNSObjectを含む超シンプルなCocoaアプリケーションを持っています。デバッガツール(組み込みWebView)をオンにすると、JavaScriptウィンドウオブジェクトにAPIが表示され、そのAPIに定義された「api」プロパティが表示されますが、APIのgetメソッドを呼び出すと、引数がシリアル化されていない - Obj-Cメソッドが呼び出されるとき、引数が欠落している。うまくいけば、示しており、以下を参照してください:

enter image description here

私は、ドキュメントを通じてコーマましたが、私は(明らかに)公開する必要のあるすべてのものを公開するために、適切な方法を設定して、と私はメソッドのビーイングを見ることができますと呼ばれる。私は行方不明の愚かな何かがありますが、この環境への相対的な初心者として、私はそれを見ていないよ。

ご協力いただきありがとうございます。

+0

、それは私はWebViewのでロードされたページ内のスクリプトからこれらのメソッドを呼び出すときのように見え、物事は大丈夫です。引数が落とされる開発者ツールを使用してJavaScriptメソッドを呼び出すときだけです。ここでも、メソッドが呼び出され、ブレークポイントは(Xcodeでは)ヒットしますが、引数はありません。困った。 –

+0

get:(NSString *)入力を取得して、(id)の入力とブレークポイント(NSLogではなく)を設定して何かが流れているかどうかを確認しようとしましたか? – JoeCortopassi

+1

JavaScriptのコードもご覧ください。 – Sam

答えて

1

使用しているXcodeのバージョンによっては、既知のエラーが発生する可能性があります。最新のバージョン以外でLLDBを使用している場合は、デバッガで適切な変数を提供していない可能性があります。その解決策は、Appleが問題を解決するまで、LLDBの代わりにGDBを使用することでした。しかし、私は彼らが最新バージョンで問題を解決したと思う。デバッガをGDBを使用するように変更し、Xcodeで正しい変数を取得しているかどうかを確認します。 (製品 - >スキームの編集 - >実行 - >デバッガ)。私はiOSでこの問題に遭遇しました。そのため、OSXへの適用性はわかりません。とにかく試してみる価値がある。

私はもともと、ここで問題に出くわした:https://stackoverflow.com/a/9485349/1147934

+0

Damnedestものですが、うまくいかないようです。しかし、提案をありがとう。 –

+0

問題ありません、申し訳ありませんが動作しませんでした。 –

2

は、あなたが送信すると、あなたのデフォルトのユーザデフォルトでYESにWebKitDeveloperExtrasを設定している - [NSUserDefaults registerDefaults:]を?

+0

ちょうど確かにそれを試みた - ダイスなし。アー!提案していただきありがとうございます。 –

+0

なぜこれが下落したのですか? – JoeCortopassi

0

appsディレクトリに格納されているローカルファイルから、自分のアプリケーションのメインスレッドでjavascriptを処理します。実行しているjs関数の先頭と末尾のトークンと、その関数に変数が含まれているかどうかを調べます。

これは、問題の良いアイデアを提供してくれることを願っています。また、jsで警告を出して、アプリケーションを実行するときに値が正しくポストされているかどうかを確認することもできます(私はあなたがすでにそれを考えていると確信していますが、言及する価値があります)。私はこれが助けて欲しい! .hファイルで

は定義:.mファイルで

NSMutableString *processedCommand; 
NSArray *commandArguments; 

:興味深いことに

// tokens 
#define kOpenToken @"<%%" 
#define kCloseToken @"%%>" 

// this will throw 
-(void)executeJScriptCommand:(NSString *)aCommand { 

[self performSelectorOnMainThread:@selector(executeThisCommand:) withObject:aCommand waitUntilDone:YES]; 
} 

// this will throw 
-(NSString *)executeCommand:(NSString *)command { 

NSString *aCommand = [[[command stringByReplacingOccurrencesOfString:kOpenToken withString:@""] 
         stringByReplacingOccurrencesOfString:kCloseToken withString:@""] 
         stringByTrimmingLeadingAndTrailingWhitespaces]; 

if ([aCommand hasPrefix:@"="]) 
{ 
    // variable. get value 
    [self getVariableFromCommand:aCommand]; 
} 
else { 
    [self executeThisCommand:aCommand]; 
} 

NSString *returnValue = [NSString stringWithString:processedCommand]; 

self.processedCommand = nil; 
self.commandArguments = nil; 

return returnValue; 
} 

-(void)executeThisCommand:(NSString *)aCommand { 

BOOL hasError = NO; 

// clear result 
self.processedCommand = nil; 
self.commandArguments = nil; 

BOOL isFromJS = NO; 
NSString *function = nil; 
NSMutableArray *commandParts = nil; 

@try { 
    // first, break the command into its parts and extract the function that needs to be called, and the (optional) arguments 
    commandParts = [[NSMutableArray alloc] initWithArray:[aCommand componentsSeparatedByString:@":"]]; 
    if ([[[commandParts objectAtIndex:0] lowercaseString] isEqualToString:@"js-call"]) { 
     isFromJS = YES; 
     [commandParts removeObjectAtIndex:0]; 
    } 

    // get our function, arguments 
    function = [[commandParts objectAtIndex:0] retain]; 
    [commandParts removeObjectAtIndex:0]; 

    if ([commandParts count] > 0){ 
     if (isFromJS == YES) { 
      NSString *arguments = [[commandParts objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
      if ([arguments length] > 0) { 
       self.commandArguments = [arguments JSONValue]; 
      } 
     } 
     else { 
      self.commandArguments = [NSArray arrayWithArray:commandParts]; 
     } 
    } 

    // build invoke 
    SEL sel = NSSelectorFromString(function); 

    if ([self respondsToSelector:sel]) { 

     [self performSelectorOnMainThread:sel withObject:nil waitUntilDone:YES]; 

     // using invocation causes a SIGABORT because the try/catch block was not catching the exception. 
     // using perform selector fixed the problem (i.e., the try/catch block now correctly catches the exception, as expected) 

    } 
    else { 
     [appDelegate buildNewExceptionWithName:@"" andMessage:[NSString stringWithFormat:@"Object does not respond to selector %@", function]]; 
    } 

} 
@catch (NSException * e) { 
    hasError = YES; 
    [self updateErrorMessage:[NSString stringWithFormat:@"Error processing command %@: %@", aCommand, [e reason]]]; 
} 
@finally { 
    [function release]; 
    [commandParts release]; 
} 

if (hasError == YES) { 
    [appDelegate buildNewExceptionWithName:@"executeThisCommand" andMessage:self.errorMessage]; 
} 
} 

// this can return nil 
-(NSString *)getQueryStringValue:(NSString *)name { 

NSString *returnValue = nil; 
if (queryString != nil) { 
    returnValue = [queryString objectForKey:[name lowercaseString]]; 
} 

return returnValue; 
} 
関連する問題