Os módulos relacionados a RPC são APMobileNetwork.framework e MPMgsAdapter. Use as interfaces em MPMgsAdapter para chamar o gateway.
Este tópico aborda o fluxo completo de integração do kit de desenvolvimento de software (SDK) do Mobile Gateway Service no iOS:
Inicializar o serviço de gateway
Chame o método a seguir para inicializar o serviço de gateway antes de fazer qualquer chamada RPC:
[MPRpcInterface initRpc];
Observações sobre atualização de versões anteriores
A partir da versão 10.1.32, não é mais necessário adicionar o arquivo Category para a classe DTRpcInterface. A camada intermediária agora lê a configuração de meta.config automaticamente. Após a atualização, remova quaisquer arquivos Category referentes a DTRpcInterface do seu projeto. A imagem a seguir mostra o arquivo a ser removido.

Gerar código RPC
Após conectar seu aplicativo ao serviço de backend no console do Mobile Gateway Service, baixe o código RPC do lado do cliente. Para obter mais informações, consulte Gerar código.
O pacote baixado gera três arquivos por serviço:

RPCDemoCloudpay_accountClient— o cliente RPC. Instancie esta classe para chamar métodos de serviço.RPCDemoAuthLoginPostReq— o modelo de solicitação. Preencha suas propriedades e passe-o para o método do cliente.RPCDemoLoginResult— o modelo de resposta. Converta o valor de retorno para este tipo para acessar os campos de resposta.
Enviar uma solicitação
Use a interface de bloco assíncrono da MPRpcInterface para executar solicitações RPC em uma thread em segundo plano. O callback de conclusão é executado automaticamente na thread principal, permitindo atualize a UI diretamente.
O exemplo a seguir em Objective-C faz login e exibe o resultado em um alerta:
- (void)sendRpc
{
__block RPCDemoLoginResult *result = nil;
[MPRpcInterface callAsyncBlock:^{
@try
{
RPCDemoLoginRequest *req = [[RPCDemoLoginRequest alloc] init];
req.loginId = @"alipayAdmin";
req.loginPassword = @"123456";
RPCDemoAuthLoginPostReq *loginPostReq = [[RPCDemoAuthLoginPostReq alloc] init];
loginPostReq._requestBody = req;
RPCDemoCloudpay_accountClient *service = [[RPCDemoCloudpay_accountClient alloc] init];
result = [service authLoginPost:loginPostReq];
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
NSError *error = [userInfo objectForKey:@"kDTRpcErrorCauseError"]; // Get detailed exception information
NSInteger code = error.code; // Get the error code from the detailed exception information
}
} completion:^{
NSString *str = @"";
if (result && result.success) {
str = @"Logon successful";
} else {
str = @"Logon failed";
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:str message:nil delegate:nil
cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
[alert show];
}];
}
Envolva chamadas RPC em
try catchpara tratar erros de gateway. Quando uma exceção for lançada, converta a causa obtida emkDTRpcErrorCauseErrordentro douserInfoda exceção paraNSErrore leia o código de erro. Consulte Códigos de resultado do gateway para visualize a lista completa.O Swift não consegue capturar
NSExceptiondo Objective-C usandodo-catch. Consulte Tratar exceções do Objective-C com segurança no Swift para conhecer a abordagem segura para Swift.
Tratar exceções do Objective-C com segurança no Swift
Contexto
O do-catch do Swift e o @try-@catch do Objective-C operam em níveis diferentes de runtime. O código Swift não consegue capturar diretamente uma NSException lançada pelo código Objective-C, o que causa falhas não tratadas em projetos com linguagens mistas.
Solução
Use o utilitário APRpcExceptionCatch. Seu método safeExecuteTry encapsula o bloco @try-@catch do Objective-C, permitindo chamar RPC com segurança a partir do Swift.
Se o Objective-C lançar uma exceção durante a execução, safeExecuteTry a captura e retorna uma DTRpcException. Se a execução for bem-sucedida, ele retorna nil.
Ao tratar a exceção, verifique DTRpcException.code para determinar o tipo de erro. Quando code.rawValue == 0, converta userInfo["kDTRpcErrorCauseError"] para NSError para recuperar o domínio, o código e a descrição subjacentes.
Versão
Suportado na versão base 10.2.3.66 e posteriores.
Código de exemplo
import MBProgressHUD
import APMobileNetwork
private func performGetIdRpcCall() {
// 1. Display the loading indicator (original start of executeRpc).
MBProgressHUD.showAdded(to: self.view, animated: true)
// 2. Define variables to receive the result and error.
var response: MPDemoUserInfo? // Replace the generic type T with the specific type MPDemoUserInfo.
var rpcError: DTRpcException?
// 3. Asynchronously execute the RPC call (original DTRpcAsyncCaller.callAsyncBlock).
DTRpcAsyncCaller.callAsyncBlock({
// 3.1. Safely execute the actual RPC call in a background thread.
rpcError = APRpcExceptionCatch.safeExecuteTry {
// This is the content of the original 'call' closure.
let client = MPDemoRpcDemoClient()
// Assign the result to the response variable.
response = client.getIdGet(self.getRequest())
}
}, completion: {
// 4. Handle the completion logic on the main thread.
DispatchQueue.main.async {
// 4.1. Hide the loading indicator.
MBProgressHUD.hide(for: self.view, animated: true)
// 4.2. Check if the RPC call has an error.
if let exception = rpcError {
// If there is an error, construct and display the error message.
var errorMsg: String
if exception.code.rawValue == 0 {
if let realError = exception.userInfo?["kDTRpcErrorCauseError"] as? NSError {
let errorString = "Error: [Domain: \(realError.domain), Code: \(realError.code), Description: \(realError.localizedDescription)]"
errorMsg = "Rpc Exception: \(errorString)"
} else {
let cause = exception.userInfo?["kDTRpcErrorCauseError"]
errorMsg = "Rpc Exception code: \(exception.code), no real error: \(cause ?? "nil")"
}
} else {
errorMsg = "Rpc Exception code: \(exception.code)"
}
// Display the error toast.
self.showErrorToast(message: errorMsg)
} else {
// 4.3. If the call is successful, process the returned data.
// This is the content of the original 'success' closure.
self.showAlert(title: "Returned Data", message: response?.description)
}
}
})
}
Personalizar configurações de solicitação
A classe DTRpcMethod descreve uma solicitação RPC. Ela armazena o nome do método, parâmetros, tipo de retorno e configurações específicas por solicitação que substituem os padrões globais.
As propriedades a seguir controlam comportamentos comuns por solicitação:
|
Propriedade |
Tipo |
Padrão |
Descrição |
|
|
BOOL |
YES |
Defina como NO para ignorar a assinatura da solicitação. |
|
|
NSTimeInterval |
20s |
Tempo limite do lado do cliente em segundos. Valores menores que 1 são ignorados e o padrão é aplicado. |
|
|
BOOL |
NO |
Defina como YES para exigir verificação de sessão. Requer configuração prévia no console do gateway. |
-
Desativar assinatura de solicitação — defina
signCheckcomo NO na instância deDTRpcMethod:-(MPDemoUserInfo *) dataPostSetTimeout:(MPDemoPostPostReq *)requestParam { DTRpcMethod *method = [[DTRpcMethod alloc] init]; method.operationType = @"com.antcloud.request.post"; method.checkLogin = NO ; method.signCheck = NO ; method.returnType = @"@\"MPDemoUserInfo\""; return [[DTRpcClient defaultClient] executeMethod:method params:@[ ]]; } -
Definir tempo limite — configure
timeoutIntervalna instância deDTRpcMethod:-(MPDemoUserInfo *) dataPostSetTimeout:(MPDemoPostPostReq *)requestParam { DTRpcMethod *method = [[DTRpcMethod alloc] init]; method.operationType = @"com.antcloud.request.post"; method.checkLogin = NO ; method.signCheck = YES ; method.timeoutInterval = 1; // Client-side timeout: time until the gateway returns a response. Default is 20s. Values less than 1 are ignored. method.returnType = @"@\"MPDemoUserInfo\""; return [[DTRpcClient defaultClient] executeMethod:method params:@[ ]]; } -
Adicionar cabeçalho de solicitação a uma única interface — use o método de extensão em
DTRpcClient:-(MPDemoUserInfo *) dataPostAddHeader:(MPDemoPostPostReq *)requestParam { DTRpcMethod *method = [[DTRpcMethod alloc] init]; method.operationType = @"com.antcloud.request.postAddHeader"; method.checkLogin = NO ; method.signCheck = YES ; method.returnType = @"@\"MPDemoUserInfo\""; // Add a request header for the interface NSDictionary *customHeader = @{@"testKey": @"testValue"}; return [[DTRpcClient defaultClient] executeMethod:method params:@[ ] requestHeaderField:customHeader responseHeaderFields:nil]; } Adicionar cabeçalho de solicitação a todas as interfaces — prefira usar um interceptador. Consulte o exemplo de código do Mobile Gateway Service para um caso completo.
A propriedade
checkLoginativa a verificação desessionna interface. Isso exige configuração prévia no console do gateway. Por padrão, ela é definida como NO.
Personalizar interceptadores RPC
O mecanismo de interceptadores do módulo RPC permite executar lógica personalizada antes do envio de uma solicitação e após sua conclusão — por exemplo, para injetar cabeçalhos de solicitação globalmente, registrar logs de solicitações ou modifique respostas.
Implementar um interceptador
Crie uma classe que esteja em conformidade com o protocolo <DTRpcInterceptor> e implemente seus dois métodos de ciclo de vida:
beforeRpcOperation:— chamado antes do envio da solicitação. Modifique a operação ou retorne-a sem alterações.-
afterRpcOperation:— chamado após o recebimento da resposta. Processe o resultado ou retorne a operação sem alterações.@interface HXRpcInterceptor : NSObject<DTRpcInterceptor> @end @implementation HXRpcInterceptor - (DTRpcOperation *)beforeRpcOperation:(DTRpcOperation *)operation{ // TODO return operation; } - (DTRpcOperation *)afterRpcOperation:(DTRpcOperation *)operation{ // TODO return operation; } @end
Registrar o interceptador
Registre o interceptador no contêiner de interceptadores da camada intermediária. Chame este método apenas uma vez durante a inicialização do aplicativo, após [MPRpcInterface initRpc]:
HXRpcInterceptor *mpTestIntercaptor = [[HXRpcInterceptor alloc] init]; // Custom sub-interceptor
[MPRpcInterface addRpcInterceptor:mpTestIntercaptor];
Criptografar dados
O RPC oferece múltiplas opções de configuração para criptografia de dados. Para obter mais informações, consulte Criptografia de dados.
Assinatura de dados (suportado na versão 10.2.3)
A versão base 10.2.3 atualize o Security Guard SDK para suportar algoritmos criptográficos nacionais (série SM). Para utilizar essa versão base, substitua a imagem do Security Guard no seu projeto pela versão V6.
A versão base 10.1.68 usa V5 por padrão. Siga estas etapas para gerar uma imagem do Security Guard V6 e substituir o arquivo yw_1222.jpg original:
Instale a interface de linha de comando do mPaaS. A interface de linha de comando (CLI) vem integrada ao plugin. Quando solicitado a remover a assinatura do Xcode, insira N.
-
Execute o comando a seguir para gerar uma nova imagem do Security Guard:
mpaas inst sgimage -c /path/to/Ant-mpaas-0D4F511111111-default-IOS.config -V 6 -t 1 -o /path/to/output --app-secret sssssdderrff --verboseNotaSubstitua o caminho do arquivo de configuração, o caminho do arquivo de saída e o valor de
--app-secretpelos seus valores reais. -
Configure o algoritmo de assinatura usando uma category em
DTRpcInterface. Sem essa etapa, o padrão seráMPAASRPCSignTypeDefault(MD5).Os valores disponíveis para o algoritmo de assinatura são:
MD5: MPAASRPCSignTypeDefault (padrão)
SHA256: MPAASRPCSignTypeSHA256
HMACSHA256: MPAASRPCSignTypeHMACSHA256
SM3: MPAASRPCSignTypeSM3
O exemplo a seguir define o algoritmo de assinatura como SM3:
#import <APMobileNetwork/DTRpcInterface.h> @interface DTRpcInterface (mPaaSDemo) @end @implementation DTRpcInterface (mPaaSDemo) - (MPAASRPCSignType)customRPCSignType { return MPAASRPCSignTypeSM3; } @end