React-native ios kakaomap 로드 안됨문제

[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.

react-native webview로 kakaomap을 구현하고 있습니다.
android 환경에서는 정상적으로 그려지는데 ios환경에선 지도 load를 못하고 있는거 같습니다.

import {View, Text, StyleSheet} from 'react-native';
import WebView, {WebViewMessageEvent} from 'react-native-webview';
import {KAKAO_API_KEY} from '../../utils/consts';
import {useState} from 'react';

interface KakaoMapProps {
  lat?: string;
  lng?: string;
  address: string;
  addressDetail?: string;
  companyName: string;
  height?: number;
  onTouchStart?: () => void;
  onTouchEnd?: () => void;
}

const KakaoMap: React.FunctionComponent<KakaoMapProps> = ({
  lat,
  lng,
  address,
  addressDetail,
  companyName,
  height = 400,
  onTouchStart,
  onTouchEnd,
}) => {
  // 주소 전체 텍스트를 미리 만들기
  const fullAddress = addressDetail ? `${address} ${addressDetail}` : address;

  const htmlContent = `
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
        <script type="text/javascript" src="https://dapi.kakao.com/v2/maps/sdk.js?appkey=${KAKAO_API_KEY}&libraries=services"></script>
        <style>
          html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
            touch-action: none;
          }
          #map {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            touch-action: none;
          }
        </style>
      </head>
      <body>
        <div id="map"></div>

        <script>
          const initMap = async () => {
            try {
              const container = document.getElementById('map');
              let position;

              if ('${lat}' && '${lng}') {
                position = new kakao.maps.LatLng(${lat || 0}, ${lng || 0});
              } else {
                try {
                  const geocoder = new kakao.maps.services.Geocoder();

                  const result = await new Promise((resolve, reject) => {
                    geocoder.addressSearch('${address}', (results, status) => {
                      if (status === kakao.maps.services.Status.OK && results?.[0]) {
                        resolve(results[0]);
                      } else {
                        reject(new Error('Geocoding failed'));
                      }
                    });
                  });

                  position = new kakao.maps.LatLng(result.y, result.x);
                } catch (error) {
                  position = new kakao.maps.LatLng(37.5666805, 126.9784147);
                }
              }

              const options = {
                center: position,
                level: 3,
                draggable: true,
                zoomable: true,
              };

              const map = new kakao.maps.Map(container, options);

              const marker = new kakao.maps.Marker({
                position: options.center
              });
              marker.setMap(map);

              const content = \`
                <div style="
                  padding: 8px 12px;
                  background: white;
                  border-radius: 8px;
                  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
                  font-size: 14px;
                  font-weight: 500;
                  max-width: 200px;
                  word-break: keep-all;
                  text-align: center;
                  border: 1px solid rgba(0,0,0,0.1);
                  position: relative;
                  transform: translateY(-42px);
                ">
                  ${companyName}
                  <div style="
                    position: absolute;
                    bottom: -5px;
                    left: 50%;
                    transform: translateX(-50%);
                    width: 0;
                    height: 0;
                    border-left: 8px solid transparent;
                    border-right: 8px solid transparent;
                    border-top: 8px solid white;
                    filter: drop-shadow(0 2px 2px rgba(0,0,0,0.1));
                  "></div>
                </div>
              \`;

              const customOverlay = new kakao.maps.CustomOverlay({
                content: content,
                position: options.center,
                yAnchor: 1
              });

              customOverlay.setMap(map);

            } catch (error) {
              console.error(error);
            }
          };

          document.addEventListener('DOMContentLoaded', initMap);
        </script>
      </body>
    </html>
  `;

  return (
    <View style={styles.container}>
      {/* 위치 아이콘과 회사명 헤더 */}
      <View style={styles.companyHeader}>
        <View style={styles.locationIconContainer}>
          <View style={styles.locationIcon} />
        </View>
        <Text style={styles.companyName} numberOfLines={1} ellipsizeMode="tail">
          {companyName}
        </Text>
      </View>

      {/* 지도 영역 */}
      <View
        style={{
          height,
          width: '100%',
          marginVertical: 0,
          borderRadius: 0,
          overflow: 'hidden',
          backgroundColor: '#f5f5f5',
        }}
        onTouchStart={onTouchStart}
        onTouchEnd={onTouchEnd}>
        <WebView
          source={{html: htmlContent}}
          style={{flex: 1}}
          // scrollEnabled={false}
          // bounces={false}
          // showsHorizontalScrollIndicator={false}
          // showsVerticalScrollIndicator={false}
          // javaScriptEnabled={true}
        />
      </View>

      {/* 주소 표시 카드 */}
      <View style={styles.addressCard}>
        <Text style={styles.addressText} numberOfLines={2}>
          {fullAddress}
        </Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    width: '100%',
    marginVertical: 15,
    borderRadius: 12,
    overflow: 'hidden',
    backgroundColor: 'white',
    shadowColor: '#000',
    shadowOffset: {width: 0, height: 2},
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3,
  },
  companyHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingVertical: 12,
    paddingHorizontal: 16,
    backgroundColor: 'white',
    borderBottomWidth: 1,
    borderBottomColor: '#f0f0f0',
  },
  locationIconContainer: {
    width: 28,
    height: 28,
    borderRadius: 14,
    backgroundColor: '#fdf5f9',
    alignItems: 'center',
    justifyContent: 'center',
    marginRight: 12,
    shadowColor: '#E8588C',
    shadowOffset: {width: 0, height: 0},
    shadowOpacity: 0.2,
    shadowRadius: 6,
    elevation: 3,
    borderWidth: 1,
    borderColor: '#f9e0eb',
  },
  locationIcon: {
    width: 12,
    height: 12,
    borderRadius: 6,
    backgroundColor: '#E8588C', // 핑크색
    shadowColor: '#E8588C',
    shadowOffset: {width: 0, height: 0},
    shadowOpacity: 0.6,
    shadowRadius: 4,
    elevation: 4,
  },
  companyName: {
    fontSize: 16,
    fontWeight: '600',
    color: '#333',
    flex: 1,
  },
  addressCard: {
    width: '100%',
    paddingVertical: 12,
    paddingHorizontal: 16,
    backgroundColor: 'white',
    borderTopWidth: 1,
    borderTopColor: '#f0f0f0',
  },
  addressText: {
    width: '100%',
    fontSize: 15,
    color: '#333',
    fontWeight: '400',
    flexWrap: 'wrap',
    flexShrink: 1,
    lineHeight: 22,
  },
});

export default KakaoMap;

inpo.plist에서 설정도 알맞게 잘 한거 같은데 어디 설정을 좀더 해줘야 할까요?

undefined is not a constructor (evaluating 'new kakao.maps.LatLng

로그찍어보면 이런 에러가 나오는거 같습니다.

@react-native-community/cli 18.0.0버전으로 React Native 프로젝트를 생성한 후,
간단한 지도를 표시하는 코드로 확인해 본 결과 iOS, Android 시뮬레이터에서 지도가 정상 표출되는 것을 확인했습니다.
아래 코드와 설정 정보, 그리고 테스트 환경도 함께 참고 부탁드립니다.

그리고 WebView의 경우, 동일한 환경에서 재현, 검증이 어려운 관계로
자세한 해결 방안을 안내드리기 어려운 점 양해 부탁드립니다.
통신 설정의 문제일 수 있고 다른 설정들의 문제가 있을 수 있기 때문에 관련 부분은 별도로 추가 확인 부탁드립니다.

//App.tsx
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';

const App = () => {
  const kakaoMapHtml = `
    <!DOCTYPE html>
    <html lang="ko">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Kakao Map</title>
      <script type="text/javascript" src="https://dapi.kakao.com/v2/maps/sdk.js?appkey=JS_APP_KEY"></script>
      <style>
        html, body, #map { margin: 0; padding: 0; width: 100%; height: 100%; }
      </style>
    </head>
    <body>
      <div id="map"></div>
      <script>
        kakao.maps.load(function() {
          var container = document.getElementById('map');
          var options = {
            center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
            level: 3
          };
          var map = new kakao.maps.Map(container, options);
        });
      </script>
    </body>
    </html>
  `;

  return (
    <View style={styles.container}>
      <WebView
        originWhitelist={['*']}
        source={{ html: kakaoMapHtml }}
        style={{ flex: 1 }}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default App;
//ios/ReactNativeProject/info.plist
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
		<key>NSAllowsLocalNetworking</key>
		<true/>

  "dependencies": {
    "@actbase/react-daum-postcode": "^1.0.4",
    "@hookform/resolvers": "^4.1.0",
    "@invertase/react-native-apple-authentication": "^2.4.1",
    "@notifee/react-native": "^9.1.8",
    "@react-native-async-storage/async-storage": "^2.1.0",
    "@react-native-firebase/app": "20.5.0",
    "@react-native-firebase/messaging": "20.5.0",
    "@react-native-seoul/kakao-login": "^5.4.1",
    "@react-native-seoul/naver-login": "^4.0.5",
    "@react-navigation/bottom-tabs": "^6.6.1",
    "@react-navigation/drawer": "^6.7.2",
    "@react-navigation/native": "^6.1.18",
    "@react-navigation/native-stack": "^7.2.0",
    "@react-navigation/stack": "^6.4.1",
    "@tanstack/react-query": "^5.62.7",
    "@types/react-native-aws3": "^0.0.4",
    "axios": "^1.7.3",
    "buffer": "^6.0.3",
    "dayjs": "^1.11.12",
    "jwt-decode": "^4.0.0",
    "lucide-react": "^0.468.0",
    "moti": "^0.29.0",
    "native-base": "^3.4.28",
    "nativewind": "^2.0.11",
    "phosphor-react-native": "^2.2.2",
    "react": "18.3.1",
    "react-dom": "^19.0.0",
    "react-hook-form": "^7.54.2",
    "react-native": "0.76.9",
    "react-native-auto-height-image": "^3.2.4",
    "react-native-aws3": "^0.0.9",
    "react-native-bootpay-api": "^13.13.42",
    "react-native-dotenv": "^3.4.11",
    "react-native-dynamic-vector-icons": "^1.3.0",
    "react-native-element-dropdown": "^2.12.2",
    "react-native-fs": "^2.20.0",
    "react-native-gesture-handler": "^2.21.2",
    "react-native-get-random-values": "^1.11.0",
    "react-native-haptic-feedback": "^2.3.3",
    "react-native-heroicons": "^4.0.0",
    "react-native-image-picker": "^7.2.3",
    "react-native-image-resizer": "^1.4.5",
    "react-native-linear-gradient": "^2.8.3",
    "react-native-reanimated": "^3.16.6",
    "react-native-reanimated-carousel": "^3.5.1",
    "react-native-safe-area-context": "^4.10.8",
    "react-native-screens": "^3.34.0",
    "react-native-splash-screen": "^3.3.0",
    "react-native-svg": "^15.11.2",
    "react-native-ui-datepicker": "^2.0.4",
    "react-native-vector-icons": "^10.1.0",
    "react-native-webview": "^13.13.5",
    "react-native-webview-bootpay": "13.13.44",
    "react-navigation-helpers": "^2.3.1",
    "uuid": "^11.0.5",
    "yup": "^1.6.1",
    "zustand": "^4.5.4"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@babel/preset-env": "^7.25.3",
    "@babel/runtime": "^7.25.0",
    "@react-native-community/cli": "15.0.1",
    "@react-native-community/cli-platform-android": "15.0.1",
    "@react-native-community/cli-platform-ios": "15.0.1",
    "@react-native/babel-preset": "0.76.9",
    "@react-native/eslint-config": "0.76.9",
    "@react-native/metro-config": "0.76.9",
    "@react-native/typescript-config": "0.76.9",
    "@types/react": "^18.2.6",
    "@types/react-native-dotenv": "^0.2.2",
    "@types/react-native-vector-icons": "^6.4.18",
    "@types/react-test-renderer": "^18.0.0",
    "babel-jest": "^29.6.3",
    "eslint": "^8.19.0",
    "jest": "^29.6.3",
    "prettier": "2.8.8",
    "react-native-base64": "^0.2.1",
    "react-native-device-info": "^14.0.4",
    "react-native-keychain": "^10.0.0",
    "react-native-svg-transformer": "^1.5.0",
    "react-test-renderer": "18.3.1",
    "tailwindcss": "3.3.2",
    "typescript": "5.0.4"
  },
  "engines": {
    "node": ">=18"
  }

ios 시뮬레이터, ios device 모두 동일하네요