Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 1개 있습니다.)

Xamarin 2.0 - 윈도우 환경의 Visual Studio에서 C#으로 iOS/Android 응용 프로그램 개발

아래의 글에서 이에 대한 자세한 소식을 들을 수 있습니다.

Announcing Xamarin 2.0
; http://blog.xamarin.com/announcing-xamarin-2.0/

그중에서 "3. Develop iOS apps in C# with Visual Studio"에 해당하는 동영상이 재미있습니다. 아래는 그 동영상에서 2개의 화면을 캡쳐한 것입니다.

ios_in_vs_1.png

ios_in_vs_2.png

보는 바와 같이, Visual Studio에서 가상 에뮬레이터를 설정하고 곧바로 Run 키를 이용해 iOS 응용 프로그램을 테스트 할 수 있습니다.




예전에 안드로이드 예제를 만든 적이 있었는데요.

안드로이드 - Hello World 실습
; https://www.sysnet.pe.kr/2/0/1378

이번엔 Xamarin 2.0으로 한번 해볼까요? ^^ 다운로드는 다음의 경로에서 간단한 사용자 정보만 입력하고 진행할 수 있습니다.

Download Xamarin Today - Build iOS, Android and Mac apps using C# and .NET.
; http://xamarin.com/download

다운로드한 파일을 실행하면 다음과 같은 구성 요소들이 설치됩니다.

ios_in_vs_3.png

  • Android SDK
  • GTK#
  • Xamarin Studio
  • Xamarin.Android for Visual Studio and Xamarin Studio
  • Xamarin.iOS for Visual Studio

이제 Visual Studio를 실행해서 "New Project"를 가보면 다음과 같이 iOS와 함께 Android 관련한 프로젝트를 생성할 수 있습니다.

ios_in_vs_4.png

"Android Application"을 선택하고 생성하면 다음과 같은 구조의 프로젝트가 생성됩니다.

[프로젝트]
    [Properties]
        AssemblyInfo.cs
    [Components]

    [Assets]
        AboutAssets.txt
        
    [Resources]
        [Drawable]
            Icon.png
        [Layout]
            Main.axml
        [Values]
            Strings.xml
    
    AboutResources.txt
    Resource.Designer.cs

Activity1.cs

이 중에서 Activity1.cs 파일의 기본 내용은 다음과 같습니다.

using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace AndroidApplication1
{
    [Activity(Label = "AndroidApplication1", MainLauncher = true, Icon = "@drawable/icon")]
    public class Activity1 : Activity
    {
        int count = 1;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            Button button = FindViewById<Button>(Resource.Id.MyButton);

            button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };
        }
    }
}

일단, 이것을 에뮬레이터에서 실행해 볼 텐데요. 윈폰의 경우에는 그냥 프로젝트에서 실행을 하면 에뮬레이터로 자동 실행이 되었지만, 안드로이드는 미리 에뮬레이터를 하나 띄워 놓아야 합니다. (참고로, 에뮬레이터 부분은 Xamarin 측에서 만든 것이 아니고, Android SDK에 포함된 것이 그대로 적용되었습니다.)

이를 위해 Visual Studio 툴바에 생긴 다음과 같은 아이콘을 누르면 됩니다.

ios_in_vs_5.png

그럼 "Android Virtual Device Manager"가 실행되고, 목록에서 원하는 가상 장치를 선택한 다음 "Start..." 버튼을 눌러주면 에뮬레이터가 실행됩니다.

ios_in_vs_6.png

이제 "F5" 키를 눌러 실행하면 현재 실행 중인 에뮬레이터 목록을 보여주면서 그중에 하나를 선택할 수 있는 창이 뜹니다.

ios_in_vs_7.png

현재는 에뮬레이터를 하나만 띄워 놓았기 때문에 목록에는 하나만 있습니다. 이를 선택해서 "OK" 버튼을 누르면 "F5" 키를 눌렀으므로 디버그 모드로 프로그램이 배포되어 실행됩니다. (사실, 에뮬레이터가 그다지 훌륭하지 못해서 오류가 발생하기도 하는데요. 그런 때는 다시 "F5"를 눌러서 배포를 해주면 됩니다.)

처음에 한번은 "Mono shared runtime" + "API 8 platform framework"이 함께 설치되기 때문에 실행 속도가 느리지만, 2번째부터는 그런대로 빠르게 배포됩니다.

아래는 예제 프로젝트가 실행된 화면을 보여줍니다. 단순히 그냥 버튼을 클릭하면 그 횟수만큼의 숫자가 증가하는 단순한 프로그램입니다. ^^

ios_in_vs_8.png

(참고로, 무료 버전의 한계로 인해 이렇게 배포된 프로그램은 24시간 후에는 동작을 안한다고 합니다. ^^;)

빌드된 /bin/Debug 폴더에 가보면 다음과 같은 파일들이 있습니다.

  • AndroidApplication1.AndroidApplication1.apk
  • AndroidApplication1.AndroidApplication1-Signed.apk
  • AndroidApplication1.dll
  • AndroidApplication1.dll.mdb
  • AndroidApplication1.pdb

apk 파일은 zip 파일인데요. 확장자를 zip으로 바꾸면 다음과 같은 구조의 폴더/파일들이 보입니다.

[META-INF]
    ANDROIDD.RSA
    ANDROIDD.SF
    MANIFEST.MF

[lib]
    [armeabi]
        libmonodroid.so
        libmono-profiler-log.so
    [armeabi-v7a]
        libmonodroid.so
        libmono-profiler-log.so
    [x86]
        libmonodroid.so
        libmono-profiler-log.so
[res]
    [drawable]
        Icon.png
        monoandroidsplash.png
    [layout]
        main.xml
        monoandroidsplash.xml




그래도, 우리의 목표는 실제 폰에 배포하는 것입니다. ^^

이를 위해서는 다음과 같은 과정을 거쳐야 한다고 Xamarin 문서에 나와 있습니다.

Part 1 - Preparing an Application for Release
; http://docs.xamarin.com/guides/android/deployment%2C_testing%2C_and_metrics/publishing_an_application/part_1_-_preparing_an_application_for_release

즉, 앞으로 4단계를 더 수행해야 합니다.

  1. Compile For Release
  2. Create a Private Key
  3. Sign the APK
  4. Zipalign the APK

1번(Compile For Release)부터 해볼까요? 우선 솔루션의 빌드 옵션을 "Release"로 바꿔주고, AssemblyInfo.cs 파일에 다음과 같은 특성을 포함시킵니다.

#if RELEASE 
[assembly: Application(Debuggable=false)] 
#else
[assembly: Application(Debuggable=true)]
#endif

이 옵션이 정상적으로 적용되려면 프로젝트 속성 창에서 "Builds" 탭의 "General" / "Conditional compilation symbols"에 "RELEASE" 상수를 입력해 두어야 합니다.

그다음 Icon을 설정하라고 하는데요. 일부 마켓 플레이스에서는 아이콘 설정이 안 되어 있으면 등록이 안 된다고 하지만, 여기서는 거기까지 해볼 수는 없으므로 그냥 생략하겠습니다.

이어서 버전 정보를 입력하라고 나오는데요. 프로젝트 속성 창에서 "Android Manifest" 탭으로 갑니다. 한 번도 manifest를 생성한 적이 없으면 "No AndroidManifest.xml found. Click to add one." 링크가 나오는데 이를 누르면 프로젝트의 "Properties" 폴더에 AndroidManifest.xml 파일이 추가되면서 편집할 수 있게 됩니다. 제 경우에는 다음과 같이 응용 프로그램 이름과 버전 정보를 넣어 주었습니다.

ios_in_vs_9.png

이렇게 하고 빌드하면 /bin/Release 폴더에는 DLL과 PDB 파일만 생성됩니다.

이어서 2번 단계(Create a Private Key)로 진행합니다. ^^

개인키를 생성하려면 JDK가 설치되어 있어야 합니다. 제 경우에는 "C:\Program Files\Java\jdk1.6.0_37\bin" 폴더에 설치되어 있고, 그 안에 포함된 keytool.exe를 이용하여 개인키를 생성했습니다.

다음은 제가 실행하고 옵션을 준 상황입니다.

D:\Settings>"C:\Program Files\Java\jdk1.6.0_37\bin\keytool.exe" -genkey -v -keystore my.keystore -alias AndPub -keyalg RSA -keysize 2048 -validity 10000
Enter keystore password:  
Re-enter new password: 
What is your first and last name?
  [Unknown]:  Kevin Arnold
What is the name of your organizational unit?
  [Unknown]:  Dev
What is the name of your organization?
  [Unknown]:  Dev
What is the name of your City or Locality?
  [Unknown]:  LA
What is the name of your State or Province?
  [Unknown]:  Washington
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Kevin Arnold, OU=Dev, O=Dev, L=LA, ST=Washington, C=US correct?
  [no]:  y

Generating 2,048 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 10,000 days
        for: CN=Kevin Arnold, OU=Dev, O=Dev, L=LA, ST=Washington, C=US
Enter key password for 
        (RETURN if same as keystore password):  
Re-enter new password: 
[Storing my.keystore]

이제 3번 단계(Sign the APK)로 넘어갑니다.

1번 단계(Compile For Release)를 마치고 빌드하는 경우 /bin/Release 폴더에 DLL과 PDB 파일만 생성되었다고 했는데요. 3번 단계를 통해서 서명된 APK 파일을 생성할 수 있습니다.

Visual Studio의 "Tools" / "Publish Android Application..." 메뉴를 실행하면 다음과 같은 창이 나오는데, 여기에 방금 전 생성했던 keystore 파일을 지정해 주어야 합니다.

ios_in_vs_10.png

"Next" 버튼을 누르면 서명된 APK 파일이 생성될 폴더를 지정할 수 있는데요. 여기서는 그냥 기본값으로 두고 "Publish" 버튼을 누르거나 원하는 값으로 바꿔도 무방합니다. (기본값은 안드로이드 프로젝트 파일 - .csproj 파일과 같은 폴더에 생성됩니다.)

여기서 좋은 소식이 하나 있는데요. 이렇게 생성된 apk 파일은 4번 단계(Zipalign the APK)까지 자동으로 반영된다고 합니다. (따라서 4번 단계는 생각할 필요가 없습니다.)

애석하게도 여기서 불편한 점이 하나 있는데요. "Publish Android Application..." 메뉴를 실행할 때마다 keystore 관련 정보를 매번 입력해 줘야 합니다. (아마도 이 부분은 나중에 개선되지 않을까 생각됩니다.)

이렇게 해서 최종 생성된 APK 파일의 내용을 보면 다음과 같습니다.

[META-INF]
    ANDPUB.RSA
    ANDPUB.SF
    MANIFEST.MF

[assemblies]
    AndroidApplication1.dll
    Mono.Android.dll
    Mono.Security.dll
    mscorlib.dll
    System.Core.dll
    System.dll

[lib]
    [armeabi-v7a]
        libmonodroid.so
[res]
    [drawable]
        Icon.png
        monoandroidsplash.png
    [layout]
        main.xml
        monoandroidsplash.xml




APK 파일을 안드로이드 폰에 배포하는 것은 간단합니다. USB 케이블로 폰과 컴퓨터를 연결해서 외장형 USB 키에 파일을 복사하듯이 APK 파일을 복사해 주어야 하는데요. 단지, 기기마다 그 방법이 약간 다른 경우가 있는 것 같습니다.

제가 실습한 폰은 LG 껀데, "Optimus LTE TAG"라고 씌여 있군요. ^^ "설정"을 실행하고 다음의 옵션들을 변경해 줍니다.

"연결" 범주
    "기본연결 형식"- "대용량 저장장치" 항목을 선택

"애플리케이션" 범주
    "알 수 없는 소스" - 항목을 선택
    "개발" 범주로 들어가서.
        "USB 디버깅" - 항목을 선택 (이 옵션 설정은 나중에 사용될 일이 있습니다.)

이제, 폰과 컴퓨터를 USB 케이블로 연결하면 폰의 저장장치가 컴퓨터에 외장하드로 인식됩니다. 탐색기를 이용해, Visual Studio로 생성했던 APK 파일을 폰으로 복사하는데요. 제 경우에는 "별도로 "/myapp" 폴더를 만들고 그 안에 APK 파일을 복사했습니다.

복사가 끝났으면 케이블을 분리합니다.

그다음 "Play 스토어"에 접속해서 "ASTRO 파일 관리자"를 다운로드 받습니다.

[apk 설치 방법] 아주 쉬운 apk 파일 설치 방법
; http://blog.naver.com/xxxooo88/90105655901

실행시켜서 "내 파일1" 항목으로 들어가면 폰을 컴퓨터에 연결했을 때와 동일한 폴더 구조를 열람할 수 있습니다. "myapp" 폴더에 apk 파일을 복사했으므로 그 안에 들어가면 "FirstTest.AndroidApp-Aligned.apk" 파일을 볼 수 있고 이 아이콘을 누르면 폰에 설치됩니다. 아래는 이렇게 해서 실행된 C# 안드로이드 앱입니다. ^^

ios_in_vs_11.png

(돈만 있다면? ^^) 이제는 C#으로 못 만들 응용 프로그램이 (현실적으로) 없군요. ^^

첨부된 파일은 위의 기본 테스트 프로젝트입니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/28/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2013-02-21 11시46분
[짜두] 오우 이회사 무지하게 발전하고 있네요~
[guest]
2013-02-22 12시42분
그러게요. ^^ 노벨에서 나올 때만 해도 위태롭더만... 이젠 확고한 위치를 잡은 것 같습니다. (이러다, 마이크로소프트에 합병되는 것이 아닌가... 하는 생각이 들 정도입니다.) 참고로, Xamarin Business Edition은 2월 마지막까지 Microsoft MVP들에게 무료라고 합니다.

http://blog.xamarin.com/for-our-friends-at-the-microsoft-mvp-summit/

For a limited time, we are offering every Microsoft MVP a free copy of Xamarin Business edition for both iOS and Android (which you may know from Twitter as MonoTouch and MonoDroid). This is a value of $1,800 dollars for free, just for being pillars of the developer community.
정성태
2013-02-25 11시55분
[wafe] 와... 근데 가격 무지 비싸네요. 회사에서 혼자 개발한다고 쳐도 Android 100만원에 iOS 100만원이라니 후덜덜...
[guest]
2013-02-25 01시19분
가격 변동에 대해서는, 향후 지켜보는 맛이 있지 않을까 생각됩니다. ^^
정성태

1  2  3  4  5  [6]  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13471정성태12/4/20232129Copilot - To enable GitHub Copilot, authorize this extension using GitHub's device flow
13470정성태12/2/20232467닷넷: 2178. C# - .NET 8부터 COM Interop에 대한 자동 소스 코드 생성 도입파일 다운로드1
13469정성태12/1/20232178닷넷: 2177. C# - (Interop DLL 없이) CoClass를 이용한 COM 개체 생성 방법파일 다운로드1
13468정성태12/1/20232171닷넷: 2176. C# - .NET Core/5+부터 달라진 RCW(Runtime Callable Wrapper) 대응 방식파일 다운로드1
13467정성태11/30/20232149오류 유형: 882. C# - Unhandled exception. System.Runtime.InteropServices.COMException (0x800080A5)파일 다운로드1
13466정성태11/29/20232372닷넷: 2175. C# - DllImport 메서드의 AOT 지원을 위한 LibraryImport 옵션
13465정성태11/28/20232102개발 환경 구성: 689. MSBuild - CopyToOutputDirectory가 "dotnet publish" 시에는 적용되지 않는 문제파일 다운로드1
13464정성태11/28/20232207닷넷: 2174. C# - .NET 7부터 UnmanagedCallersOnly 함수 export 기능을 AOT 빌드에 통합파일 다운로드1
13463정성태11/27/20232092오류 유형: 881. Visual Studio - NU1605: Warning As Error: Detected package downgrade
13462정성태11/27/20232140오류 유형: 880. Visual Studio - error CS0246: The type or namespace name '...' could not be found
13461정성태11/26/20232205닷넷: 2173. .NET Core 3/5+ 기반의 COM Server를 registry 등록 없이 사용하는 방법파일 다운로드1
13460정성태11/26/20232164닷넷: 2172. .NET 6+ 기반의 COM Server 내에 Type Library를 내장하는 방법파일 다운로드1
13459정성태11/26/20232190닷넷: 2171. .NET Core 3/5+ 기반의 COM Server를 기존의 regasm처럼 등록하는 방법파일 다운로드1
13458정성태11/26/20232193닷넷: 2170. .NET Core/5+ 기반의 COM Server를 tlb 파일을 생성하는 방법(tlbexp)
13457정성태11/25/20232145VS.NET IDE: 187. Visual Studio - 16.9 버전부터 추가된 "Display inline type hints" 옵션
13456정성태11/25/20232438닷넷: 2169. C# - OpenAI를 사용해 PDF 데이터를 대상으로 OpenAI 챗봇 작성 [1]파일 다운로드1
13455정성태11/25/20232322닷넷: 2168. C# - Azure.AI.OpenAI 패키지로 OpenAI 사용파일 다운로드1
13454정성태11/23/20232658닷넷: 2167. C# - Qdrant Vector DB를 이용한 Embedding 벡터 값 보관/조회 (Azure OpenAI) [1]파일 다운로드1
13453정성태11/23/20232205오류 유형: 879. docker desktop 설치 시 "Invalid JSON string. (Exception from HRESULT: 0x83750007)"
13452정성태11/22/20232289닷넷: 2166. C# - Azure OpenAI API를 이용해 사용자가 제공하는 정보를 대상으로 검색하는 방법파일 다운로드1
13451정성태11/21/20232420닷넷: 2165. C# - Azure OpenAI API를 이용해 ChatGPT처럼 동작하는 콘솔 응용 프로그램 제작파일 다운로드1
13450정성태11/21/20232242닷넷: 2164. C# - Octokit을 이용한 GitHub Issue 검색파일 다운로드1
13449정성태11/21/20232338개발 환경 구성: 688. Azure OpenAI 서비스 신청 방법
13448정성태11/20/20232616닷넷: 2163. .NET 8 - Dynamic PGO를 결합한 성능 향상파일 다운로드1
13447정성태11/16/20232480닷넷: 2162. ASP.NET Core 웹 사이트의 SSL 설정을 코드로 하는 방법
13446정성태11/16/20232416닷넷: 2161. .NET Conf 2023 - Day 1 Blazor 개요 정리
1  2  3  4  5  [6]  7  8  9  10  11  12  13  14  15  ...