다음을 통해 공유


Android 에뮬레이터 및 iOS 시뮬레이터에서 로컬 웹 서비스에 연결

Browse sample.샘플을 찾아봅니다. 샘플 찾아보기

많은 모바일 및 데스크톱 앱은 웹 서비스를 사용합니다. 소프트웨어 개발 단계에서는 웹 서비스를 로컬로 배포하고 Android 에뮬레이터 또는 iOS 시뮬레이터에서 실행되는 앱에서 사용하는 것이 일반적입니다. 이렇게 하면 호스트된 엔드포인트에 웹 서비스를 배포할 필요가 없으며 앱과 웹 서비스가 모두 로컬로 실행되므로 간단한 디버깅 환경을 사용할 수 있습니다.

팁 (조언)

.NET 10 이상을 사용하는 경우 Aspire 통합 을 사용하여 로컬 웹 서비스에 대한 연결을 간소화하는 것이 좋습니다. Aspire는 플랫폼별 네트워킹 구성, 서비스 검색 및 개발 터널을 자동으로 처리하여 이 문서에 설명된 수동 구성의 대부분을 제거합니다.

Windows 또는 MacCatalyst에서 실행되는 .NET 멀티 플랫폼 앱 UI(.NET MAUI) 앱은 개발 인증서를 신뢰할 수 있는 경우 별도의 작업 없이 HTTP 또는 HTTPS를 통해 로컬에서 실행되는 ASP.NET Core 웹 서비스를 사용할 수 있습니다. 그러나 앱이 Android 에뮬레이터 또는 iOS 시뮬레이터에서 실행 중이고 웹 서비스가 HTTP 또는 HTTPS를 통해 실행되는지 여부에 따라 프로세스가 다른 경우 추가 작업이 필요합니다.

로컬 컴퓨터 주소

Android 에뮬레이터와 iOS 시뮬레이터는 모두 로컬 컴퓨터에서 HTTP 또는 HTTPS를 통해 실행되는 웹 서비스에 대한 액세스를 제공합니다. 그러나 각 경우의 로컬 머신 주소가 다릅니다.

Android

Android Emulator의 각 인스턴스는 개발 머신 네트워크 인터페이스에서 격리되며 가상 라우터 뒤에서 실행됩니다. 따라서 에뮬레이트된 디바이스에서는 개발 머신 또는 네트워크의 다른 에뮬레이터 인스턴스를 볼 수 없습니다.

그러나 각 에뮬레이터의 가상 라우터는 10.0.2.2 주소가 개발 머신에서 호스트 루프백 인터페이스(127.0.0.1)의 별칭인 미리 할당된 주소를 포함하는 특별한 네트워크 공간을 관리합니다. 따라서 상대 URI를 통해 /api/todoitems/ GET 작업을 노출하는 로컬 웹 서비스가 있는 경우, Android 에뮬레이터에서 실행되는 앱은 http://10.0.2.2:<port>/api/todoitems/ 또는 https://10.0.2.2:<port>/api/todoitems/로 GET 요청을 전송하여 작업을 소비할 수 있습니다.

iOS

iOS 시뮬레이터는 호스트 머신 네트워크를 사용합니다. ** 따라서 시뮬레이터에서 실행되는 앱은 컴퓨터의 IP 주소 또는 localhost 호스트 이름을 통해 로컬 머신에서 실행되는 웹 서비스에 연결할 수 있습니다. 예를 들어, 상대 URI를 통해 /api/todoitems/ GET 작업을 노출하는 로컬 웹 서비스가 있는 경우, iOS 시뮬레이터에서 실행되는 앱은 GET 요청을 http://localhost:/api/todoitems/ 또는 https://localhost:/api/todoitems/로 보내 작업을 사용할 수 있습니다.

주의

Windows에서 iOS 시뮬레이터를 통해 .NET MAUI 앱을 실행하면, 해당 앱이 Windows 용 원격 iOS 시뮬레이터에 표시됩니다. 그러나 쌍을 이루는 Mac에서 앱이 실행되고 있습니다. 따라서 Mac에서 실행되는 iOS 앱에 대해 Windows에서 실행되는 웹 서비스에 대한 localhost 액세스 권한이 없습니다.

HTTP를 통해 실행되는 로컬 웹 서비스

Android 에뮬레이터 또는 iOS 시뮬레이터에서 실행되는 .NET MAUI 앱은 HTTP를 통해 로컬로 실행되는 ASP.NET Core 웹 서비스를 사용할 수 있습니다. 이렇게 하려면 .NET MAUI 앱 프로젝트와 ASP.NET Core 웹 서비스 프로젝트를 구성하여 평문 HTTP 트래픽을 허용하도록 설정합니다.

.NET MAUI 앱에서 로컬 웹 서비스의 URL을 정의하는 코드에서 웹 서비스 URL이 HTTP 체계와 올바른 호스트 이름을 지정하는지 확인합니다. 클래스 DeviceInfo를 사용하여 앱이 실행 중인 플랫폼을 검색할 수 있습니다. 그러면 올바른 호스트 이름을 다음과 같이 설정할 수 있습니다.

public static string BaseAddress =
    DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";

DeviceInfo 클래스에 대한 자세한 내용은 "디바이스 정보"를 참조하세요.

또한 Android에서 앱을 실행하려면 필요한 네트워크 구성을 추가하고 iOS에서 앱을 실행하려면 ATS(Apple Transport Security)를 옵트아웃해야 합니다. 자세한 내용은 Android 네트워크 구성iOS ATS 구성을 참조하세요.

또한 ASP.NET Core 웹 서비스가 HTTP 트래픽을 허용하도록 구성되어 있는지 확인해야 합니다. ASP.NET Core 웹 서비스 프로젝트의 profiles launchSettings.json 파일 섹션에 HTTP 프로필을 추가하여 이 작업을 수행할 수 있습니다.

{
  ...
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "api/todoitems",
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    ...
  }
}

그런 다음 Android 에뮬레이터 또는 iOS 시뮬레이터에서 실행되는 .NET MAUI 앱은 http 프로필로 시작된 경우 HTTP를 통해 로컬에서 실행되는 ASP.NET Core 웹 서비스를 사용할 수 있습니다.

Android 네트워크 구성

Android에서 평문 로컬 트래픽을 활성화하는 두 가지 주요 방법이 있습니다.

모든 도메인에 대해 평문 네트워크 트래픽 허용

모든 도메인에 대한 평문 네트워크 트래픽은 Application 속성의 UsesCleartextTraffic 값을 true로 설정하여 활성화할 수 있습니다. 이 작업은 .NET MAUI 앱 프로젝트의 Platforms Android MainApplication.cs 파일에서 수행되어야 하며, 프로덕션 앱에서 실수로 사용되지 않도록 #if DEBUG로 래핑해야 합니다.

#if DEBUG
[Application(UsesCleartextTraffic = true)]
#else
[Application]
#endif
public class MainApplication : MauiApplication
{
    public MainApplication(IntPtr handle, JniHandleOwnership ownership)
        : base(handle, ownership)
    {
    }

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

주의

UsesCleartextTraffic 속성은 네트워크 보안 구성 파일이 있을 경우 Android 7.0(API 24) 이상에서 무시됩니다.

localhost 도메인에 대해 평문 네트워크 트래픽 허용

네트워크 보안 구성 파일을 만들어 localhost 도메인의 평문 네트워크 트래픽을 허용할 수 있습니다. 이 작업은 .NET MAUI 앱 프로젝트의 Platforms\Android\Resources\xml 폴더에 network_security_config.xmlXML 파일을 추가하여 수행할 수 있습니다. XML 파일은 다음 구성을 지정해야 합니다.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">10.0.2.2</domain>
  </domain-config>
</network-security-config>

주의

network_security_config.xml 파일의 빌드 작업이 AndroidResource설정되어 있는지 확인합니다.

그런 다음, .NET MAUI 앱 프로젝트의 Platforms\Android\AndroidManifest.xml 파일의 애플리케이션 노드에서 networkSecurityConfig 속성을 구성합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config" ...>
        ...
    </application>
</manifest>

네트워크 보안 구성 파일에 대한 자세한 내용은 developer.android.com의 네트워크 보안 구성을 참조하세요.

iOS ATS 구성

iOS에서 텍스트 지우기 로컬 트래픽을 사용하도록 설정하려면 .NET MAUI 앱에서 ATS(Apple Transport Security)를 옵트아웃해야 합니다. 이 작업은 .NET MAUI 앱 프로젝트의 Platforms\iOS\Info.plist 파일에 다음 구성을 추가하여 수행할 수 있습니다.

<key>NSAppTransportSecurity</key>    
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

ATS에 대한 자세한 내용은 developer.apple.com의 "안전하지 않은 네트워크 연결 방지" 문서를 참조하세요.

HTTPS를 통해 실행되는 로컬 웹 서비스

Android 에뮬레이터 또는 iOS 시뮬레이터에서 실행되는 .NET MAUI 앱은 HTTPS를 통해 로컬로 실행되는 ASP.NET Core 웹 서비스를 사용할 수 있습니다. 이를 사용하도록 설정하는 프로세스는 다음과 같습니다.

  1. 컴퓨터에서 자체 서명된 개발 인증서를 신뢰합니다. 자세한 내용은 개발 인증서 신뢰를 참조하세요.
  2. 로컬 머신의 주소를 지정합니다. 자세한 내용은 로컬 머신 주소 지정을 참조하세요.
  3. 로컬 개발 인증서 보안 검사를 무시합니다. 자세한 내용은 인증서 보안 검사 무시를 참조하세요.

각 항목을 차례차례 설명하겠습니다.

개발 인증서 신뢰

.NET Core SDK를 설치하면 로컬 사용자 인증서 저장소에 ASP.NET Core HTTPS 개발 인증서가 설치됩니다. 그러나 인증서가 설치되었지만 신뢰할 수는 없습니다. 인증서를 신뢰하려면 한 번만 수행하여 dotnet dev-certs 도구를 실행합니다.

dotnet dev-certs https --trust

다음 명령은 dev-certs 도구에 대한 도움말을 제공합니다.

dotnet dev-certs https --help

또는 HTTPS를 사용하는 ASP.NET Core 2.1(이상) 프로젝트를 실행할 때 Visual Studio는 개발 인증서가 누락되었는지 검색하고, 누락된 경우 설치한 후 신뢰할 것을 요구합니다.

주의

ASP.NET Core HTTPS 개발 인증서가 자체 서명됩니다.

머신에서 로컬 HTTPS를 사용하도록 설정하는 방법에 대한 자세한 내용은 로컬 HTTPS 사용을 참조하세요.

로컬 머신 주소 지정

.NET MAUI 앱에서 로컬 웹 서비스의 URL을 정의하는 코드에서 웹 서비스 URL이 HTTPS 체계와 올바른 호스트 이름을 지정하는지 확인합니다. 클래스 DeviceInfo를 사용하여 앱이 실행 중인 플랫폼을 검색할 수 있습니다. 그러면 올바른 호스트 이름을 다음과 같이 설정할 수 있습니다.

public static string BaseAddress =
    DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";

DeviceInfo 클래스에 대한 자세한 내용은 "디바이스 정보"를 참조하세요.

인증서 보안 검사 무시

Android 에뮬레이터에서 실행되는 .NET MAUI 앱이 로컬 보안 웹 서비스를 호출하려고 하면 인증 경로에 대한 신뢰 루트를 찾을 수 없다는 메시지와 함께 java.security.cert.CertPathValidatorException 예외가 발생합니다. 마찬가지로 iOS 시뮬레이터에서 실행 중인 .NET MAUI 앱이 로컬 보안 웹 서비스를 호출하려고 할 때, 서버의 인증서가 유효하지 않다는 메시지를 표시하는 NSURLErrorDomain 오류가 발생합니다. 이러한 오류는 로컬 HTTPS 개발 인증서가 자체 서명되고 자체 서명된 인증서가 Android 또는 iOS에서 신뢰할 수 없기 때문에 발생합니다. 따라서 앱이 로컬 보안 웹 서비스를 사용하는 경우 SSL 오류를 무시해야 합니다.

이 작업은 인스턴스 HttpClientHandler를 사용자 지정 ServerCertificateCustomValidationCallback으로 구성하여, HttpClient 클래스가 HTTPS를 통한 localhost 통신을 신뢰하도록 지시하는 방식으로 수행할 수 있습니다. 다음 예제에서는 localhost 인증서 유효성 검사 오류를 무시하는 HttpClientHandler 인스턴스를 만드는 방법을 보여 줍니다.

var handler = new HttpClientHandler();

#if DEBUG
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
    if (cert != null && cert.Issuer.Equals("CN=localhost"))
        return true;
    return errors == System.Net.Security.SslPolicyErrors.None;
};
#endif

var client = new HttpClient(handler);

중요

위의 코드는 localhost 인증서 유효성 검사 오류를 무시하지만 디버그 빌드에서만 무시합니다. 이 방법은 프로덕션 빌드에서 보안 인시던트 방지

Android 에뮬레이터 또는 iOS 시뮬레이터에서 실행되는 .NET MAUI 앱은 HTTPS를 통해 로컬로 실행되는 ASP.NET Core 웹 서비스를 사용할 수 있습니다.