Objective-C - обратный вызов из JS с использованием webview является ненормальным, если вызов дважды - PullRequest
0 голосов
/ 05 декабря 2018

Я использовал web3js для взаимодействия с узлом Ethereum в моем iOS-приложении с Objective-C.Поскольку некоторые функции в js не синхронизированы, мне нужно установить функцию обратного вызова в моем коде Obj-c, чтобы получить результаты.Это работает хорошо.Но если я вызываю их последовательно (в функции), это работает ненормально.Вот мой фрагмент кода,

//Objective-C
    // js callback 
    _jsContext[@"replyJSonString"] = ^(NSString* dicResult, NSString* error) {
    DDLogDebug(@"reply from js: %@ - error: %@", dicResult, error);
    if(error && ![error isEqualToString:@"null"]) {
        _asyncCallResult = error; return;
    }
    _asyncCallResult = dicResult;
    dispatch_semaphore_signal(_semaphore);



-(NSString*) global_getMemberInfo:(NSString*) pid withAPP:(NSString*) app
{
    DDLogDebug(@"global_getMemberInfo");
    NSString* ret = [self exeJSFunctionFromAsync:JS_FUNC_GET_MEMBER_INFO withParam:@[pid, app]];
    if([self isError:ret])
        @throw [DTCO_Exception exceptionWithReason:@"global_getMemberInfo function error" userInfo:nil];
    return ret;
}

-(NSString*) member_getMemberDetails:(NSString*) pid withTag:(NSString*) tag
{
    DDLogDebug(@"member_getMemberDetails");
    NSString* ret = [self exeJSFunctionFromAsync:JS_FUNC_GET_MEMBER_DETAILS withParam:@[pid, tag]];
    if([self isError:ret])
        @throw [DTCO_Exception exceptionWithReason:@"global_getMemberDetails function error" userInfo:nil];
    return ret;
}


-(NSString*) exeJSFunctionFromAsync:(NSString*) func withParam: (NSArray*) param
{
    JSValue* jsFunc = _jsContext[func];
    if([[jsFunc toString] isEqualToString:@"undefined"] )
        @throw [DTCO_Exception exceptionWithReason:@"JS file is not loaded correctly." userInfo:nil];
    JSValue* ret = [jsFunc callWithArguments:param];

    dispatch_semaphore_wait(_semaphore, dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC));

    DDLogDebug(@"exe [%@] ret: %@", func, _asyncCallResult);
    return _asyncCallResult;
}

Javascript

// javascript
function global_getMemberInfo(pid, app) {
    try
        {
            if(typeof global_web3 != 'undefined') {
                var globalContract = new global_web3.eth.Contract(globalContractABI, globalContractAddress,
                                           {from:pid, gasPrice: '2000000000'});
               var contractFunc = globalContract.methods.get_member_info(pid, 'idgo');
               contractFunc.call(function(error, result) {                                       replyJSonString(JSON.stringify(result), error);
                });
            }else{
                return "web3 undefined!";
            }
        }
        catch(e)
        {
            return  "exception: "+e;
        }
    }

    function member_getMemberDetails(pid, tag) {
        try
        {
            if(typeof global_web3 != 'undefined') {
                var memberContract = new global_web3.eth.Contract(memberContractABI, memberContractAddress,
                                              {from:pid, gasPrice: '2000000000'});
               var contractFunc = memberContract.methods.getDetail(pid, tag);
                contractFunc.call(function(error, result) { replyJSonString(JSON.stringify(result), error);
                                    });
            }else{
                return "web3 undefined!";
            }
        }
        catch(e)
        {
            return  "exception: "+e;
        }
    }

Если я вызову две функции одновременно,

+(NSString*) getMemberInfo:
{
    ID_MemberInfo* info = [api global_getMemberInfo:@"0x300..." 

    ID_MemberDetails* details = [api member_getMemberDetails:@"0x300..." andTag:@"tag"];
    ...
}

, вторая будетненормально, вот журнал

2018-12-05 14:42:13:007 IDGODemoSDK[25744:1093451] global_getMemberInfo
2018-12-05 14:42:13:024 IDGODemoSDK[25744:1093451] exe [member_getMemberDetails] ret: (null)
2018-12-05 14:42:13:209 IDGODemoSDK[25744:1093519] reply from js: {...} - error: null
2018-12-05 14:42:13:007 IDGODemoSDK[25744:1093451] member_getMemberDetails
2018-12-05 14:42:20:018 IDGODemoSDK[25744:1093451] exe [member_getMemberDetails] ret: (null)
2018-12-05 14:42:20:019 IDGODemoSDK[25744:1093451] getMemberDetails EX - global_getMemberDetails function error
2018-12-05 14:42:20.020 IDGODemoSDK[25744:1093451] global_getMemberDetails function error
2018-12-05 14:42:20:032 IDGODemoSDK[25744:1093519] reply from js: {...} - error: null

, похоже, что поток [1093519] (поток обратного вызова) был заблокирован при втором вызове.Независимо от того, как долго я жду, обратный вызов вызывался сразу после того, как я перестал ждать во втором вызове.Похоже, что-то не так при обратном вызове во второй раз.Если две функции js не вызывают обратный вызов obj-c, это работает хорошо.(Это хорошо работает отдельно.)

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...