The only thing I can think of is that we recently changed the server's SSL certificate because the intermediate certificate was missing, and the vector tiles weren't working on Android because the system didn't trust the server.
Summary
On iOS, while developing locally (
Код: Выделить всё
npx expo run:iosПосле распределения того же кода через Testflight (выпустить сборку), точно тот же стиль прекращает получение заголовка токена на стороне сервера и векторные Tiles Fail (401/403). Нет изменений в стиле/коде между Dev и Tf.
Это только влияет на запросы плитки (…/{z}/{x}/{y} .pbf запросы). Другие выборы, которые я делаю в приложении (Axios Prear), включают в себя штраф за заголовка. It looks like the header set via @maplibre/maplibre-react-native is either not attached or gets lost in release.
Environment
- @maplibre/maplibre-react-native: 10.2.0
- React Native: 0.81.4
- expo : 54.0.10 (управляемый рабочий процесс, предварительно присутствует из -за выставки: ios ), построенный с eas
- ios : 26 (воспроизводился на iPhone 14 Pro/ios 26)
: 26 (воспроизводился на iPhone 14 Pro/ios Distribution : testflight (App Store Connect), выпуск сборки (без изменений кода с локального) - server : https (допустимый сертификат), Custom Koop/Arcgis Backend ожидание авторизации: Bearer
только -это пропущенный заголовок авторизации по запросам плитки в tf.
минимальный стиль (векторные источники)
Код: Выделить всё
{
"version": 8,
"sources": {
"countries": {
"type": "vector",
"tiles": [
"https://:8446/boundaries/rest/services/IPCERT/countries/VectorTileServer/{z}/{x}/{y}.pbf"
],
"minzoom": 0,
"maxzoom": 6
},
"provinces": {
"type": "vector",
"tiles": [
"https://:8446/boundaries/rest/services/IPCERT/provinces/VectorTileServer/{z}/{x}/{y}.pbf"
],
"minzoom": 4.5,
"maxzoom": 9
},
"municipalities": {
"type": "vector",
"tiles": [
"https://:8446/boundaries/rest/services/IPCERT/municipalities/VectorTileServer/{z}/{x}/{y}.pbf"
],
"minzoom": 7.5
}
},
"layers": [
{ "id": "countries", "type": "fill", "source": "countries" },
{ "id": "provinces", "type": "fill", "source": "provinces" },
{
"id": "municipalities",
"type": "fill",
"source": "municipalities"
}
]
}
< /code>
код для установки заголовка (минимальный) < /h2>
// useMapAuthHeader.ts
import { useEffect, useState } from "react";
import { AppState } from "react-native";
import {
addCustomHeader,
removeCustomHeader,
} from "@maplibre/maplibre-react-native";
import { useAuth } from "@/Context/AuthContext";
const HEADER_NAME = "Authorization";
export function useMapAuthHeader() {
const { token } = useAuth();
const [isAuthReady, setIsAuthReady] = useState(false);
useEffect(() => {
try {
removeCustomHeader(HEADER_NAME);
if (token) {
addCustomHeader(HEADER_NAME, `Bearer ${token}`);
setIsAuthReady(true);
}
} catch {}
return () => {
try {
removeCustomHeader(HEADER_NAME);
} catch {}
};
}, [token]);
// Re-apply on foreground (iOS can recreate sessions)
useEffect(() => {
const sub = AppState.addEventListener("change", (s) => {
if (s === "active" && token) {
try {
removeCustomHeader(HEADER_NAME);
addCustomHeader(HEADER_NAME, `Bearer ${token}`);
} catch {}
}
});
return () => sub.remove();
}, [token]);
return { isAuthReady };
}
i gate. На практике это задерживает любую сеть MapView до настройки заголовка Auth.
Код: Выделить всё
// Pseudocode of the guards I have around MapView mount
const { combinedMapStyle, isMapStyleReady } = useMapStyle();
const { isAuthReady } = useMapAuthHeader();
const { prewarmDone } = useKoopPrewarm(isMapStyleReady, combinedMapStyle);
if (!isMapStyleReady || !prewarmDone || !isAuthReady) {
return ; // avoid mounting MapView until ready
}
return ;
Prewarm behavior (works with header)
To reduce backend pressure I “prewarm” Koop by fetching one плитка на источник через axios с таким же токеном. These prewarm calls reach the server with Authorization: Bearer … both locally and in TestFlight, and succeed (200/204 no content).
Only MapLibre tile requests in TestFlight are missing the header.
Snippet (simplified):
Код: Выделить всё
await api.get(tileUrl, {
responseType: "arraybuffer",
transformResponse: [],
// axios has Authorization header through my API client interceptors
});
В условиях выполнения I переписывает URL-адреса источников для добавления серверных фильтров (например,? Lspaisids = [123] ,? Это влияет только на строку запроса , а не хост.
Это переписывание не связано с задачей заголовка: локально (dev) Сервер по -прежнему видит авторизацию независимо от дополнительных параметров запроса; В TestFlight заголовок отсутствует, даже если я полностью отключаю переписывание. class = "Lang-Swift PrettyPrint-Override">
Код: Выделить всё
import Expo
import React
import ReactAppDependencyProvider
@UIApplicationMain
public class AppDelegate: ExpoAppDelegate {
var window: UIWindow?
var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
var reactNativeFactory: RCTReactNativeFactory?
public override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = ExpoReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
bindReactNativeFactory(factory)
#if os(iOS) || os(tvOS)
window = UIWindow(frame: UIScreen.main.bounds)
// Initialize MapLibre custom headers (restored)
MLRNCustomHeaders().initHeaders()
MLRNCustomHeaders().addHeader("sECrEt", forHeaderName: "Authorization")
factory.startReactNative(
withModuleName: "main",
in: window,
launchOptions: launchOptions)
#endif
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// Linking API
public override func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
}
// Universal Links
public override func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
}
}
class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
// Extension point for config-plugins
override func sourceURL(for bridge: RCTBridge) -> URL? {
// needed to return the correct URL for expo-dev-client.
bridge.bundleURL ?? bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
#else
return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
< /code>
Специально эти строки предназначены для того, чтобы гарантировать, что пользовательские заголовки доступны в приложении: < /p>
MLRNCustomHeaders().initHeaders()
MLRNCustomHeaders().addHeader("sECrEt", forHeaderName: "Authorization")
Код: Выделить всё
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "MLRNCustomHeaders.h"
Код: Выделить всё
MLRNCustomHeaders().initHeaders()
MLRNCustomHeaders().addHeader("sECrEt", forHeaderName: "Authorization")
< /code>
не были признаны в моем Swift AppDelegate. Я не был уверен, как заменить или перенести эту логику в V11, поэтому я остался на V10.2.0. или пример кода? Короткий фрагмент или ссылка DOCS поможет мне повторно испытать V11. < /P>
Эта проблема компиляции /миграции отделена от текущей проблемы:
отсутствующий заголовок авторизации в Testflight IOS происходит на V10.2.0 с кодом, который в противном случае работает нормально. Приложение локально с NPX Expo Run: ios [*] Любые известные различия между отладкой и выпуском, которые влияют на пользовательские заголовки для запросов плитки. iOS code headers are attached so I can open a PR.
[/list]
Workarounds
- I can “prewarm” the Koop cache using Axios with auth to reduce load, but this doesn’t fix the missing header on MapLibre tile fetches themselves.
- Источники стиля иногда переписываются во время выполнения для добавления параметров запросов (например,? lspaisids = [123] < /code>). Это не меняется, появляется ли заголовок на стороне сервера; Только Testflight против локального составляет разницу.работает локально, но заголовок исчезает в ios testflight [/b] только для запросов на векторную плитку . Похоже, что заголовки, установленные через глобальный API, не применяются к выбросам плитки в выпуске.
Код: Выделить всё
addCustomHeader('Authorization', 'Bearer …')
@maplibre/maplibre-react-national версия
визу. Это происходит?Что вы попробовали?Код: Выделить всё
expo-env-info 2.0.7 environment info: System: OS: macOS 15.4.1 Shell: 5.9 - /bin/zsh Binaries: Node: 22.18.0 - ~/.nvm/versions/node/v22.18.0/bin/node Yarn: 1.22.22 - /usr/local/bin/yarn npm: 10.9.3 - ~/.nvm/versions/node/v22.18.0/bin/npm Watchman: 2025.03.10.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.16.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 24.5, iOS 18.5, macOS 15.5, tvOS 18.5, visionOS 2.5, watchOS 11.5 IDEs: Android Studio: 2024.3 AI-243.24978.46.2431.13208083 Xcode: 16.4/16F6 - /usr/bin/xcodebuild npmPackages: expo: 54.0.10 => 54.0.10 expo-router: ~6.0.8 => 6.0.8 expo-updates: ~29.0.11 => 29.0.11 react: 19.1.0 => 19.1.0 react-dom: 19.1.0 => 19.1.0 react-native: 0.81.4 => 0.81.4 react-native-web: ^0.21.0 => 0.21.1 npmGlobalPackages: eas-cli: 16.19.3 expo-cli: 6.3.12 Expo Workflow: bare(также попробовал ключ нижней части).Код: Выделить всё
addCustomHeader("Authorization", "Bearer ") - Удал и заново добавил заголовок на переднем плане приложения/фон через AppState .
- Задержка монтажа До тех пор, пока заголовок Auth, Style и Prewarm не стали готовыми. retrought).
- Отключенный URL -сигнал отключения URL -адреса выполнения (PARAMS PARMAS), чтобы исключить его. Mlrncustomheaders (). Initheaders () и .addheader (...) .
- Создано и протестирован с точно таким же кодом локально () и через Testflight (eas).
Код: Выделить всё
npx expo run:ios
Подробнее здесь: https://stackoverflow.com/questions/797 ... not-attach
Мобильная версия