Android 에뮬레이터 및 iOS 시뮬레이터에서 로컬 웹 서비스로 커넥트

Browse sample. 샘플 찾아보기

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

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 에뮬레이터에서 실행되는 앱은 GET 요청을 http://10.0.2.2:<port>/api/todoitems/ 보내거나 https://10.0.2.2:<port>/api/todoitems/전송하여 작업을 사용할 수 있습니다.

iOS

iOS 시뮬레이터는 호스트 머신 네트워크를 사용합니다. 따라서 시뮬레이터에서 실행되는 앱은 컴퓨터 IP 주소 또는 호스트 이름을 통해 localhost 로컬 컴퓨터에서 실행되는 웹 서비스에 연결할 수 있습니다. 예를 들어 상대 URI를 통해 /api/todoitems/ GET 작업을 노출하는 로컬 웹 서비스가 있는 경우 iOS 시뮬레이터에서 실행되는 앱은 GET 요청을 http://localhost:<port>/api/todoitems/ 보내거나 https://localhost:<port>/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 웹 서비스 프로젝트의 시작설정.json 섹션에 HTTP 프로필을 profiles 추가하여 수행할 수 있습니다.

{
  ...
  "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에서 텍스트 지우기 로컬 트래픽을 사용하도록 설정하려면 네트워크 보안 구성 파일을 만들어야 합니다. 이 작업은 .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 에뮬레이터 java.security.cert.CertPathValidatorException 에서 실행되는 .NET MAUI 앱에서 로컬 보안 웹 서비스를 호출하려고 하면 인증 경로에 대한 신뢰 앵커를 찾을 수 없음을 나타내는 메시지와 함께 throw됩니다. 마찬가지로 iOS 시뮬레이터에서 실행되는 .NET MAUI 앱에서 로컬 보안 웹 서비스를 호출하려고 하면 서버에 대한 인증서가 유효하지 않음을 나타내는 메시지와 함께 오류가 발생 NSURLErrorDomain 합니다. 이러한 오류는 로컬 HTTPS 개발 인증서가 자체 서명되고 자체 서명된 인증서가 Android 또는 iOS에서 신뢰할 수 없기 때문에 발생합니다. 따라서 앱이 로컬 보안 웹 서비스를 사용하는 경우 SSL 오류를 무시해야 합니다.

구성된 버전의 네이티브 HttpMessageHandler 클래스 HttpClient 를 생성자에 전달하여 이 작업을 수행할 수 있습니다. 그러면 클래스가 HttpClient HTTPS를 통한 localhost 통신을 신뢰하도록 지시합니다. 클래스는 HttpMessageHandler 추상 클래스이며, Android에서 구현하는 클래스는 클래스에서 제공 AndroidMessageHandler 되고 해당 구현은 iOS에서 클래스에서 NSUrlSessionHandler 제공됩니다.

다음 예제에서는 HttpS를 통한 localhost 통신을 AndroidMessageHandler 신뢰하도록 Android의 클래스와 NSUrlSessionHandler iOS의 클래스를 구성하는 클래스를 보여 줍니다.

public class HttpsClientHandlerService
{
    public HttpMessageHandler GetPlatformMessageHandler()
    {
#if ANDROID
        var handler = new Xamarin.Android.Net.AndroidMessageHandler();
        handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
        {
            if (cert != null && cert.Issuer.Equals("CN=localhost"))
                return true;
            return errors == System.Net.Security.SslPolicyErrors.None;
        };
        return handler;
#elif IOS
        var handler = new NSUrlSessionHandler
        {
            TrustOverrideForUrl = IsHttpsLocalhost
        };
        return handler;
#else
     throw new PlatformNotSupportedException("Only Android and iOS supported.");
#endif
    }

#if IOS
    public bool IsHttpsLocalhost(NSUrlSessionHandler sender, string url, Security.SecTrust trust)
    {
        if (url.StartsWith("https://localhost"))
            return true;
        return false;
    }
#endif
}

Android에서 메서드는 GetPlatformMessageHandler 개체를 반환합니다 AndroidMessageHandler . 이 메서드는 GetPlatformMessageHandler 개체의 ServerCertificateCustomValidationCallbackAndroidMessageHandler 속성을 로컬 HTTPS 개발 인증서에 대한 인증서 보안 검사 결과를 무시하는 콜백으로 설정합니다.

iOS에서 메서드는 GetPlatformMessageHandler 해당 TrustOverrideForUrl 속성을 대리자의 서명과 일치하는 대리자로 IsHttpsLocalHost 설정하는 개체를 NSUrlSessionHandler.NSUrlSessionHandlerTrustOverrideForUrlCallback 반환 NSUrlSessionHandler 합니다. URL이 IsHttpsLocalHost .로 시작되면 대리자가 반환 true 됩니다.https://localhost

그러면 결과 개체를 HttpClientHandler 디버그 빌드의 HttpClient 생성자에 인수로 전달할 수 있습니다.

#if DEBUG
            HttpsClientHandlerService handler = new HttpsClientHandlerService();
            HttpClient client = new HttpClient(handler.GetPlatformMessageHandler());
#else
            client = new HttpClient();
#endif

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