全部產品
Search
文件中心

Mobile Platform as a Service:iOS 常見問題

更新時間:Jul 13, 2024

本文介紹接入 iOS 過程中常見的問題及相應的解決方案。

注意事項

  • H5 容器初始化時,最好指定所有 H5 頁面的基類和 WebView 的基類,便於統一處理。a1

  • 前端在開發離線包時,對應路徑及檔案名稱中不允許有中文字元,否則會導致用戶端離線包解壓失敗。

  • 離線包中各資源路徑的絕對長度不要超過 100 字元,否則導致用戶端 tar 包解壓失敗,頁面白屏。

如何解決 H5 容器定位位移問題

解答:在使用 mPaaS 容器的過程中可能會遇到 H5 容器定位位移的問題,請參考以下方法進行設定更新:

- (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    //跳過 LBS 定位
    [LBSmPaaSAdaptor sharedInstance].shouldSkipLBSLocation = YES;

    .......
    
}

預置離線包使用 H5_json.json 檔案不生效

解答:在 10.1.32 基準中,只支援 plist 格式。在 10.1.60 基準中,plist 和 JSON 格式都支援。

如何擷取已安裝的離線包應用資訊

解答:參考代碼 NSDictionary *installedApps = [NAMServiceGet() installApps:nil];

如何強制更新全部離線包資訊

解答:可以使用封裝的 requestAllNebulaApps 方法進行全量更新。

[[MPNebulaAdapterInterface shareInstance]requestAllNebulaApps:^(NSDictionary *data, NSError *error) {

 }];

在 iOS 13 中的 vux-ui pulldown 組件在 H5 容器中滑動卡死時如何處理

解答:這是因為觸發了 UIWebview 在 iOS 系統中的 bug,可以考慮切換成 WKWebview 或更換前端組件。切換為 WKWebview 的方法請參考文檔 mPaaS 10.1.60 適配 WKWebView

如何查看當前應用登入的所有 JSAPI 和 Plugins

解答:開啟一個 H5 頁面,進入 Xcode View 層級頁面,在 lldb 控制台使用 po [[PSDService sharedInstance] jsApis] 查看所有 JSAPI。同理使用 po [[PSDService sharedInstance] plugins] 查看所有註冊的 Plugins。1

如何在 JSAPI 或 Plugin 中擷取當前 H5 頁面的 UIViewController 和 Webview 對象

解答:在實際執行過程中,Plugin 可直接拿到參數 event.context,JSAPI 中可擷取到 context,在上下文 PSDContext 對象中,可以取到您想要的所有資訊或引用,比如當前控制器 event.currentViewController 的引用,當前 WebView 的引用 context.currentViewController.psdContentView 等等。23

如何擷取當前頁面的 WebView

解答:當前 H5 頁面的 WebView 是當前 VC 的一個屬性,可通過 vc.psdContentView 擷取,在 JSAPI 或 Plugin 中可通過上面的方法擷取當前頁面的 VC。

說明

在 H5 頁面基類擷取當前頁面的 WebView 時,請在 viewWillAppear 方法中。viewDidLoad 方法中 WebView 未建立,如果使用該方法,取到的值會為 nil。

image.png

如何擷取當前頁面載入時前端傳入的啟動參數

解答:直接擷取當前 VC 的 psdScene.createParam.expandParams 屬性。

image.png

如何限制 JSAPI 只在某個特定離線包中起作用

解答:在 JSAPI 的實際執行方法中,擷取當前頁面所屬離線包的 appId,決定是否執行邏輯即可。5

如何攔截頁面 URL

解答:您可以自訂 Plugin,通過監聽事件來實現。

  • 監聽事件名稱 [PSDProxy addEventListener:kEvent_Proxy_Request_Start_Handler withListener:self useCapture:YES];

  • 攔截處理。

else if ([kEvent_Proxy_Request_Start_Handler isEqualToString:event.eventType]
        && [event isKindOfClass:[PSDProxyEvent class]] ){

        NSLog(@"-----kNBEvent_Scene_NavigationItem_Right_Setting_Click----");
        PSDProxyEvent *proxyEvent = (PSDProxyEvent*) event;
        NSMutableURLRequest *redirectReq = proxyEvent.request.mutableCopy;
        NSString *appId = event.context.currentSession.createParam.expandParams[@"appId"];

        NAMApp *app = [NAMServiceGet() findApp:appId version:nil];
        NSString *fallBackUrl = app.fallback_host;
        NSString *vhost = app.vhost;;
        NSString *url = redirectReq.URL.absoluteString;


       NSLog(@"url__%@______fallBackUrl:%@",url,fallBackUrl);
       if ([url containsString:@"www.baidu.com"]) {
           [proxyEvent preventDefault];

 }}

如何在當前 H5 頁面載入前,攔截當前頁面 URL

解答:在 H5 頁面的基類中,實現 UIWebView 的生命週期的代理方法中,監聽 kEvent_Navigation_Start 事件,在頁面載入之前攔截,擷取當前頁面的 WebView 和 URL 進行相關處理。

image.png

如何在 Native 手動調用 JSAPI

解答:有時 Native 端可能需要您在當前頁面手動調用某個 JSAPI 介面,可通過調用當前 VC 的以下介面實現。

image.png

為什麼本地預置的離線包載入不生效

解答:預置資源套件載入失敗一般為預置包版本和包資訊不匹配,測試本地預置離線包時,請先斷開網路,避免離線包有更新,確保載入的是用戶端本地預置的版本。

檢查本地預置的離線包資訊與 Plist 中配置的包資訊是否一致,包括 app_id、version、main_url 等資訊。c11

為什麼控制台發布新版本離線包後用戶端不能正常載入到新包

解答:在查看此問題解決方案前,確認您已理解 離線封裝更新原理,用戶端不能正常載入新包,離線包渲染在任一階段都有可能出錯,下面將一一進行排查:

  1. 查看全量更新離線包的 RPC 返回結果,在控制台搜尋“bizType: 4”確認返回的離線包詳情,確認已經拉取了控制台發布的最新包資訊。

  2. 上一步檢查通過後,在載入離線包的 finish 回調方法裡查看離線包資訊,確保為控制台發布的最新包,且 error 的值為 nil,檢查離線包的 app_id、version、main_url 等是否正確。

  3. 上一步檢查通過後,查看沙箱目錄下離線包是否解壓成功(若當前離線包有引用全域資源套件中內容,此解壓目錄下同樣需要有全域資源套件)。c3

  4. 若上一步中沙箱目錄下無對應離線包,可先暫時關閉離線包驗簽,刪除 App 重新運行。若關閉驗簽後載入正常,說明離線包加簽私密金鑰和用戶端驗簽公開金鑰不一致,請更新用戶端對應的公開金鑰資訊。c4

  5. 若上述步驟檢查都通過,離線封裝更新仍失敗,可用 Safari 調試對應 H5 頁面,具體查看報錯原因。如全域資源套件路徑不正確,離線包載入的 URL 不存在等。c5

全域資源套件載入失敗

解答:當通過 Safari 調試判斷出全域資源套件載入失敗時,可按下述步驟具體排查:

  1. 檢查全域資源套件是否註冊。

  2. 上一步檢查通過後,查看沙箱目錄下離線包是否解壓成功。c13

  3. 檢查引用的全域資源套件中資源檔路徑是否正常,且保證引用路徑中無中文字元。

為什麼開啟某個離線包 H5 頁面會白屏或出現 400 錯誤

解答:頁面白屏或出現 400 錯誤,一般為本地離線包載入失敗導致使用了線上 fallback 地址,而對應頁面的 fallback 地址不存在,導致頁面載入失敗。

  1. 按上述離線包問題排查用戶端離線包載入失敗的原因。

  2. 針對載入線上 fallback 地址失敗的問題,確認對應離線包版本產生正確,且已在控制台已上傳,包括普通離線包和全域資源套件,具體請參考 產生離線包

  3. 預置離線包若出現線上 fallback 地址失敗的問題,先保證預置的離線包在控制台同樣也上傳。

  4. 保證本地預置包資訊中 fallback_base_url 與從控制台下載的 h5_json.json 設定檔中 fallback_base_url 一致。 1112

  5. 並且 fallback_base_url + main_url 拼接的地址在瀏覽器上可正常載入。

    image.png

怎樣禁止 H5 頁面的手勢側滑返回功能

解答:支援由前端 H5 頁面禁止和原生 H5 容器基類禁止。

  1. 前端 H5 頁面禁止:調用 setGestureBack JSAPI 實現。適用於某一個頁面需要禁止手勢側滑返回的情境AlipayJSBridge.call('setGestureBack',{val:false});

  2. 原生 H5 容器基類禁止:在基類的 viewDidAppear 方法中調用系統禁止側滑返回的介面,同時設定 guestBack 參數。適用於多個或所有 H5 頁面需要禁止手勢側滑返回的情境。

     -(void)viewDidAppear:(BOOL)animated {
         [super viewDidAppear:animated];
    
         self.options.gestureBack = NO;
         if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
             self.navigationController.interactivePopGestureRecognizer.enabled = NO;
         }
     }

如何判斷當前頁面是小程式中的頁面

解答:擷取當前頁面所在的 session,調用 isTinyAppWithSession 介面判斷。程式碼範例如下:

PSDSession *session = self.psdSession;
BOOL isTinyApp = [NBUtils isTinyAppWithSession:session];

H5 頁面如何傳遞自訂參數

解答:根據傳參方式,分為以下幾種情境:

  • 原生 - H5:調用 startH5ViewControllerWithParams 方法時傳遞 [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"key1":@"value1"}];

  • 原生 - 離線包:調用 startH5ViewControllerWithNebulaApp 方法時傳遞 [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithNebulaApp:@{@"appId":@"70000000",@"param":@{@"key2":@"value2"}}];

  • H5 - H5:調用 pushWindow 時將自訂參數寫在 passData 中。

    AlipayJSBridge.call('pushWindow', {
    // 要開啟頁面的 URL
    url: 'https://m.taobao.com/',
    // 開啟頁面的配置參數
    param: {
      readTitle: true,    //自動讀取 title
      showOptionMenu: false,    // 隱藏右邊菜單
    	transparentTitle:'always',
    },
    // 用於給新開的頁面傳遞參數,可選
    // 在新開的頁面使用 AlipayJSBridge.startupParams 可以擷取到 passData
    passData: {
      key1: "key1Value",
      key2: "key2Value"
    }
    });
  • H5 - 離線包:調用 startApp JSAPI 時將自訂參數寫在 param 中。

    AlipayJSBridge.call('startApp', {
    appId: '70000000',
    param: {
    key1:'value1'
    }
    }, function(result) {
    // noop
    });

如何在 H5 頁面擷取傳遞的參數

解答:分為前端擷取和原生擷取兩種情境:

  • 前端擷取:通過 startupParams 方法擷取當前頁面的啟動參數。

    AlipayJSBridge.startupParams

  • 原生擷取:通過當前頁面所在的 VC 對象擷取。

    // 當前頁面的啟動參數
    NSDictionary *expandParams = self.psdScene.createParam.expandParams;
    NSLog(@"[mpaas] expandParams: %@", expandParams);

如何攔截 JSAPI 呼叫

解答:可以自訂 Plugin,通過監聽事件來實現。

  • 監聽事件名稱:kEvent_Invocation_Event_Start

  • 攔截處理:擷取到 JSAPI 的名稱、傳遞的參數等。

    else if([kEvent_Invocation_Event_Start isEqualToString:event.eventType]) {
          PSDInvocationEvent * invocationEvent = (PSDInvocationEvent *)event;
          NSString * apiName = invocationEvent.invocationName;
          if([apiName isEqualToString:@"setOptionMenu"] || [apiName isEqualToString:@"showOptionMenu"] ) {
              NSLog(@"wwww");
          }
      }