[Unity3D] 구글 플레이 게임 서비스 & 애플 게임 센터 연동 (1/2) #설정편 링크 : http://minhyeokism.tistory.com/70



* 본격적으로 진행하기 전에 한 가지 말씀드리자면 


UnityEngine.Social.localUser 는 Androiod와 iOS 두 플랫폼을 모두 지원하고


현재 앱의 Platform을 알아서 판단하여


Android는 구글 플레이 게임 서비스의 api를


iOS는 애플 게임선터의 api를 호출하도록 할 수 있습니다.


다시 말해,



1
2
3
4
    Social.localUser.Authenticate((bool success) =>
    {
 
    });
cs



위 처럼 Social.localUser.~~~ 를 하면 Android 든 iOS 든 알아서! 문제없이! 작동한다는 뜻입니다.


그러나 특별한 상황에서는 구분을 명확하게 해야할 필요가 있습니다. 그럴 때에는


- Android일 경우 PlayGamesPlatform. 을


- iOS일 경우 GameCenterPlatform. 을 


쓰시면 됩니다.


또한, iOS 앱에서도 PlayGamesPlatform.을 사용하면 게임센터가 아닌 구글 플레이에 로그인하도록 할 수도 있습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    void Start()
    {
#if UNITY_ANDROID
 
        PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
            .EnableSavedGames()
            .Build();
 
        PlayGamesPlatform.InitializeInstance(config);
 
        PlayGamesPlatform.DebugLogEnabled = true;
 
        PlayGamesPlatform.Activate();
 
#elif UNITY_IOS
 
        GameCenterPlatform.ShowDefaultAchievementCompletionBanner(true);
 
#endif
    }
cs



제일 먼저 Initialization과 Configuration 부분입니다.


구글의 저장된 게임 기능을 사용할 것이라면 (for Android)


.EnableSavedGames() 를 config에 추가해주세요.


마지막 줄에 PlayGamesPlatform.Activate() 를 해줘야 모든 기능이 작동합니다.


iOS는 특별한 config 빌드가 없어도 됩니다.



* 한 가지 주의할 점!


iOS 앱에서 안드로이드 용인 PlayGamesPlatform.Activate() 가 호출되면


애플 게임센터 api가 제대로 작동하지 않는 것을 경험했습니다.


때문에 게임센터에 접근하려면 위 처럼 코드를 #if 와 #elif 로 나눠주는 것이 좋습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    public void SignIn()
    {
        Social.localUser.Authenticate((bool success) =>
        {
            if (success)
            {
                // to do ...
                // 로그인 성공 처리
            }
            else
            {
                // to do ...
                // 로그인 실패 처리
            }
        });
    }
cs



Sign In 부분입니다.


Social.localUser로 Authenticate 하고 있기 때문에


Android와 iOS 둘 다 작동합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    public void SignIn()
    {
#if UNITY_ANDROID
 
        PlayGamesPlatform.Instance.Authenticate((bool success) =>
        {
            if (success)
            {
                // to do ...
                // 구글 플레이 게임 서비스 로그인 성공 처리
            }
            else
            {
                // to do ...
                // 구글 플레이 게임 서비스 로그인 실패 처리
            }
        });
 
#elif UNITY_IOS
 
        Social.localUser.Authenticate((bool success) =>
        {
            if (success)
            {
                // to do ...
                // 애플 게임 센터 로그인 성공 처리
            }
            else
            {
                // to do ...
                // 애플 게임 센터 로그인 실패 처리
            }
        });
 
#endif
    }
cs



필요에 따라 이렇게 명확하게 구분하여 구현해도 됩니다.


(GameCenterPlatform 에는 Authenticate가 없기때문에 Social.localUser로 접근함)





플레이 게임 서비스 Sign Out 은 이렇게 하시면 됩니다.


(게임 센터 Sign Out api는 별도로 확인하지 못 함)



다음으로 업적과 리더보드를 구현해보겠습니다.



1
2
3
4
5
6
7
8
9
10
11
    public void UnlockAchievement(int score)
    {
        if (score >= 100)
        {
#if UNITY_ANDROID
            PlayGamesPlatform.Instance.ReportProgress(GPGSIds.achievement_100, 100f, null);
#elif UNITY_IOS
            Social.ReportProgress("Score_100", 100f, null);
#endif
        }
    }
cs



먼저, 업적을 잠금해제하는 코드 예시입니다.


Social.ReportProgress("업적ID", 0f~100f, callback);


첫 번째 파라미터에는 잠금해제 할 업적의 고유 ID를 입력해주고

(설정편에서 생성된 GPGSIds.cs에 있는 static 변수를 가져다 쓸 것)


두 번째 파라미터에는 해당 업적의 진행도(0f~100f) 를 넣어줍니다.

진행도가 존재하는 업적의 경우 진행도를 0과 100사이의 float형으로 환산하여 넣어주면 되고

단순히 조건을 충족하면 바로 잠금해제되는 업적일 경우 바로 100f를 넣어주면 됩니다.


세 번째 파라미터에는 callback 함수를 넣어줍니다.

콜백이 필요 없는 경우에는 null



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    public void ShowAchievementUI()
    {
        // Sign In 이 되어있지 않은 상태라면
        // Sign In 후 업적 UI 표시 요청할 것
        if (Social.localUser.authenticated == false)
        {
            Social.localUser.Authenticate((bool success) =>
            {
                if (success)
                {
                    // Sign In 성공
                    // 바로 업적 UI 표시 요청
                    Social.ShowAchievementsUI();
                    return;
                }
                else
                {
                    // Sign In 실패 처리
                    return;
                }
            });
        }
 
        Social.ShowAchievementsUI();
    }
cs



업적 UI를 열려면 


Social.ShowAchievementsUI() 를 호출하면 됩니다.


* 소셜에 로그인이 되어있지 않다면 로그인 후 재요청하는 예외처리를 해주는 것이 좋습니다.



    



좌 : Android - Google Play Games Services 업적 UI 스크린샷

우 : iOS - Apple Game Center 목표 달성 UI 스크린샷



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    public void ReportScore(int score)
    {
#if UNITY_ANDROID
 
        PlayGamesPlatform.Instance.ReportScore(score, GPGSIds.leaderboard_score, (bool success) =>
        {
            if (success)
            {
                // Report 성공
                // 그에 따른 처리
            }
            else
            {
                // Report 실패
                // 그에 따른 처리
            }
        });
 
#elif UNITY_IOS
 
        Social.ReportScore(score, "Leaderboard_ID", (bool success) =>
            {
                if (success)
                {
                    // Report 성공
                    // 그에 따른 처리
                }
                else
                {
                    // Report 실패
                    // 그에 따른 처리
                }
            });
        
#endif
    }
cs



다음은 리더보드에 점수를 기록하는 코드 예시입니다.


Social.ReportScore(점수, "리더보드 고유 ID", callback);


첫 번째 파라미터에는 플레이어가 기록한 점수를 넣어줍니다.


두 번째 파라미터에는 점수를 올릴 리더보드의 고유 ID를 넣어줍니다.

(설정편에서 생성된 GPGSIds.cs에 있는 static 변수를 가져다 쓸 것)


세 번째 파라미터에는 callback 함수를 넣어줍니다.

콜백이 필요 없는 경우에는 null


* ReportScore() 함수 내부에서 플레이어의 기록된 점수와 파라미터로 날아온 점수의 높낮이를 비교하고 필터링하기 때문에

 더 낮은 점수일 경우의 예외처리를 할 필요가 없습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    public void ShowLeaderboardUI()
    {
        // Sign In 이 되어있지 않은 상태라면
        // Sign In 후 리더보드 UI 표시 요청할 것
        if (Social.localUser.authenticated == false)
        {
            Social.localUser.Authenticate((bool success) =>
            {
                if (success)
                {
                    // Sign In 성공
                    // 바로 리더보드 UI 표시 요청
                    Social.ShowLeaderboardUI();
                    return;
                }
                else
                {
                    // Sign In 실패 
                    // 그에 따른 처리
                    return;
                }
            });
        }
 
#if UNITY_ANDROID
        PlayGamesPlatform.Instance.ShowLeaderboardUI();
#elif UNITY_IOS
        GameCenterPlatform.ShowLeaderboardUI("Leaderboard_ID", UnityEngine.SocialPlatforms.TimeScope.AllTime);
#endif
    }
cs



리더보드의 UI를 열려면


Social.ShowLeaderboardUI()

PlayGamesPlatform.Instance.ShowLeaderboardUI()

GameCenterPlatform.ShowLeaderboardUI("순위표 고유 ID", TimeScope)


를 상황에 맞게 호출합니다.


* 마찬가지로, 소셜에 로그인이 되어있지 않다면 로그인 후 재요청하는 예외처리를 해주도록 합니다.





리더보드 UI를 열 때


위 처럼 TimeScope 를 정해서 넘겨주면 원하는 기간동안의 순위표를 보게할 수도 있습니다.


AllTime - 전체 기간 순위표

Today - 오늘 순위표

Week - 이번 주 순위표



    



Android - Google Play Games Services 리더보드 UI 스크린샷



    



iOS - Apple Game Center 순위표 UI 스크린샷




이상으로 포스팅을 마치겠습니다.


궁금한 점이 있다면 댓글 남겨주세요.



안녕하세요.


이번 포스팅의 주제는 Google Play Games 플러그인 연동하기 입니다!


유니티 프로젝트에


     Android - 구글 플레이 게임 서비스 (Google Play Games Services)

     iOS - 애플 게임 샌터 (Apple Game Center)


를 연동하고


1. 로그인(SignIn), 2. 로그아웃(SignOut), 3. 업적(Achievement), 4. 리더보드(Leaderboard) 


기능을 구현해보도록 하겠습니다.


물론 Google Play Games plugin for Unity - Github 사이트에 영문으로


업적, 리더보드, 저장된 게임, 퀘스트 등 다양한 기능 연동 가이드가 있습니다.


링크 : https://github.com/playgameservices/play-games-plugin-for-unity





우선 위 링크에서 [Clone or download] -> [Download.ZIP] 하여 플러그인을 다운로드합니다.


압축을 풀고 내용물을 보면





이렇게 되어있는데


맨 위 current-build 폴더에 최신 버전 플러그인.unitypackage가 들어있습니다.


(이 플러그인은 구글 플레이 게임서비스와 애플 게임센터 두 플랫폼 다 지원함)




유니티 프로젝트에 import 해둡니다.




[Android - 구글 플레이 게임 서비스 설정]



먼저, 구글 플레이 개발자 콘솔로 이동하여 (회원가입 후) 로그인 합니다.


플레이 콘솔 사이트 링크 : https://play.google.com/apps/publish/?hl=ko


(Google Play Developer Console의 탐색 기능과 디자인이 업데이트되었으며 이름이 Play Console로 변경되었습니다 - 17년 4월 기준)





우측에 [애플리케이션 만들기] 버튼을 클릭합니다. (플레이 콘솔에 앱을 추가하지 않은 경우만)





언어를 설정하고 제목을 입력한 후 [만들기] 하고


스토어 등록정보 등 기타 내용을 채워서 출시 조건을 맞춰줍니다.





애플리케이션 설정을 완료했다면 [게임 서비스]로 이동하여 [새 게임 추가]를 클릭합니다.





게임 이름을 입력하고 카테고리 선택 후 [계속] 합니다.


애플리케이션 설정과 마찬가지로 [게임 세부정보]에 내용을 채워줍니다.





그 다음 [연결된 앱]으로 이동하고 플랫폼을 선택합니다.





이전에 만들어 두었던 애플리케이션을 게임 서비스와 연결하는 과정입니다.


앱 이름과 패키지 이름, 기타 설정을 마치고 [저장하고 계속] 합니다.





연결이 정상적으로 완료된 모습입니다.







업적과 리더보드를 각각 추가해줍니다.


(참고로, 업적이나 리더보드 아이콘을 넣어주지 않으면 디폴트 아이콘이 보여집니다.)


그러고 나면 하단에 [리소스 받기] 가 보이실텐데요 한번 클릭해 봅시다.





위 처럼 [리소스 내보내기] 라고 뜨는데요


Android 앱은 [ANDROID] 탭을 눌러서 내용을 복사해둡니다.


(iOS 앱은 [OBJECTIVE-C] 탭을 눌러서 복사)


이제 유니티로 돌아옵니다.





플러그인이 정상적으로 임포트 되었다면 Window에 Google Play Games 메뉴가 생깁니다.


그럼 [Window] -> [Google Play Games] -> [Setup] -> [Android setup] 해줍니다.





위와 같은 팝업창이 뜨면 [Resources Definition]


아까 복사해 두었던 리소스를 붙여넣기 합니다.


[Web App Client ID]는 웹 게임용 변수이므로 패스하고 [Setup] 버튼을 누릅니다.





Setup이 완료되었습니다.


[OK]를 누르고 로딩을 기다리면





위 처럼 GPGSIds 라는 .cs 파일이 생성되었을 것입니다.





앞서 만들어둔 업적과 리더보드의 ID를 string 형식으로 담고있는 모습입니다.


업적을 잠금해제하거나 리더보드에 스코어를 올릴 때


static 클래스 GPGSIds의 string 변수를 가져다 쓸 것입니다.




[iOS - 애플 게임센터 설정]



아이튠즈 커넥트 사이트로 이동하여 회원가입 후 로그인 합니다.


iTunes Connect 사이트 링크 : https://itunesconnect.apple.com





로그인 후 메인 페이지에서 [나의 앱] 으로 이동합니다.





[나의 앱] 페이지 좌상단에 있는 [+ 버튼] 을 누른 후 [신규 앱] 을 클릭합니다.


이미 등록된 앱이 있다면 앱 아이콘을 클릭합니다.





플랫폼, 이름, 기본 언어, 번들 ID, SKU 를 입력하고 [생성] 합니다.





앱이 정상적으로 생성되었다면 앱 아이콘을 눌러 앱 페이지로 이동합니다.


그 다음 [앱 내 추가 기능] -> [Game Center] 메뉴로 이동합니다.





순위표와 목표 달성 (각각 리더보드와 업적을 뜻함) 이


비어있는 모습입니다.


먼저 순위표 옆에 있는 +버튼을 눌러줍니다.





개별 순위표를 [선택] 합니다.





개별 순위표 정보를 채워줍니다.


그리고 하단 순위표 현지화에 있는 [언어 추가] 를 눌러줍니다.





현지화 할 언어를 선택합니다.


나머지 정보를 입력하고 (이미지는 선택사항, 이미지를 올리지 않으면 디폴트 이미지가 보여짐) [Save] 합니다.


이제 리더보드가 준비되었습니다.


다음으로 업적을 추가해 봅시다.





목표 달성 옆에 있는 +버튼을 눌러서 업적을 생성합니다.


업적 정보를 입력하고 하단 목표 달성 현지화에 있는 [언어 추가] 를 눌러줍니다.





마찬가지로 현지화 할 언어를 선택하고 제목과 설명을 입력하고 [Save] 합니다.


위는, 업적 아이콘을 원하는 이미지로 직접 설정해 준 모습입니다.





다시 유니티로 돌아와서


[Window] -> [Google Plat Games] -> [Setup] -> [iOS setup...] 합니다.






팝업 창이 뜨면 플레이 콘솔 [리소스 내보내기] 에서 [OBJECTIVE-C] 를 선택하고 


복사 & 붙여넣기 합니다.


그리고 [Setup] 해줍니다.




자, 이제 정말로 연동할 준비가 다 되었습니다!


다음 편에 계속됩니다!


[Unity3D] 구글 플레이 게임 서비스 & 애플 게임 센터 연동 (2/2) #코드편 링크 : http://minhyeokism.tistory.com/72



개발자를 힘들게 하는 애플의 IPv6 검수 통과하기

목차

IPv6에 대해서 최소한도로 알아보기
Apple에서 공지한 iOS 앱에 대한 검수 내용 살펴보기
개발자들이 주의해야 할 사항
IPv6 로 인한 App Reject 사례와 참고 자료

지난 WWDC15 이후에 Apple 개발자 페이지에 올라온 News인 Supporting IPv6 in iOS 9에서는 IPv6-only network service가 지원돼야 한다는 정책을 발표하고, 2016년도 초부터 해당 사항을 앱 리뷰 시에 적용한다고 했습니다. 뉴스를 보자마자 머리가 띵해져 왔지만, 사실 이때까지만 해도 잘 와 닿지 않았던 이유는 IPv6 Only Network를 일반인들에게 제공하는 국내 ISP는 존재하지 않았기 때문에 Apple이 무엇을 원하는지, 그리고 도대체 어느 수준까지 앱 리뷰할 때 Reject 기준이 될지 머릿속에서 혼란이 왔습니다.

물론 Apple답게 테스트 방법에 대한 가이드라인이 있었기 때문에 해당 문서를 보고 제가 담당하고 있는 SDK에 대한 테스트를 진행해봤지만, 역시나 IPv6 Only network에서는 통신이 이루어지지 않았습니다.

처음에는 사내 네트워크 환경부터 SDK의 소스 코드 등을 살펴 보았지만, 크게 문제가 있어 보이지는 않았습니다. 하지만 컴퓨터는 거짓말을 하지 않는지라 SDK 내에서 사용하고 있는 Open Source 라이브러리를 살펴보니, IPv6를 지원할 수 없는 상태였습니다. 따라서 해당 문제를 해결하고 나니 정상적으로 IPv6 환경에서의 테스트가 성공하게 되었습니다.

이제부터의 글은 제가 IPv6에 대한 이슈를 처리하기 위하여 알아본 기본적인 내용에 대해서 적어보도록 하겠습니다.

IPv6에 대해서 최소한도로 알아보기

주소의 길이가 128bit로써 급격하게 늘어나는 인터넷 연결 기기와 이에 따른 IPv4 주소의 고갈에 대응하여 제안되었습니다. IPv6는 기존 Ipv4와의 호환성을 최대한 유지할 수 있는 방향으로 설계되어, 대부분의 기존 프로토콜의 수정 없이 IPv6 상에서 동작할 수 있습니다.

주소 표현 방법

주소의 표현은 128bit의 주소공간으로써 16bit(2octet)를 16진수로 표현하여 8자리로 구성합니다.

2001:0db8:85a3:0000:0000:8a2e:0370:7334

위의 Address Literal은 아래와 같이 표현할 수 있습니다.
0000 은 0으로 축약할 수 있으며, 아래와 같이 생략할 수도 있습니다.

2001:0db8:85a3:8a2e:0370:7334

IPv6의 특성

IPv6의 특성에 대해서 간략하게 알아보겠습니다.

  • IP 주소의 확장: IPv4의 기존 32 비트 주소공간에서 벗어나, IPv6는 128 비트 주소공간을 제공합니다.
  • 호스트 주소 자동 설정: IPv6 호스트는 IPv6 네트워크에 접속하는 순간 자동적으로 네트워크 주소를 부여 받습니다. 이는 네트워크 관리자로부터 IP 주소를 부여 받아 수동으로 설정해야 했던 IPv4에 비해 중요한 사항입니다.
  • 패킷 크기 확장: IPv4에서 패킷 크기는 64킬로바이트로 제한되어 있었습니다. IPv6의 점보그램 옵션을 사용하면 특정 호스트 사이에는 임의로 큰 크기의 패킷을 주고받을 수 있도록 제한이 없어지게 됩니다. 따라서 대역폭이 넓은 네트워크를 더 효율적으로 사용할 수 있습니다.
  • 효율적인 라우팅: IP 패킷의 처리를 신속하게 할 수 있도록 고정크기의 단순한 헤더를 사용하는 동시에, 확장헤더를 통해 네트워크 기능에 대한 확장 및 옵션기능의 확장이 용이한 구조로 정의 했습니다.
  • 플로 레이블링(Flow Labeling): 플로 레이블(flow label) 개념을 도입, 특정 트래픽은 별도의 특별한 처리(실시간 통신 등)를 통해 높은 품질의 서비스를 제공할 수 있도록 합니다.
  • 인증 및 보안 기능: 패킷 출처 인증과 데이터 무결성 및 비밀 보장 기능을 IP 프로토콜 체계에 반영 하였습니다. IPv6 확장헤더를 통해 적용할 수 있습니다.
  • 이동성: IPv6 호스트는 네트워크의 물리적 위치에 제한 받지 않고 같은 주소를 유지하면서도 자유롭게 이동할 수 있습니다. 이와 같은 모바일 IPv6는 RFC 3775와 RFC 3776에 기술되어 있습니다. (IPv4에도 모바일 IP가 정의되어 있지만 아직 많이 사용되지 않습는다.)

참조 : https://ko.wikipedia.org/wiki/IPv6

Apple에서 공지한 iOS 앱에 대한 검수 내용 살펴보기

iPhone 앱에 대한 검수

1.png
많은 개발자들이 야근을 하게한 원흉인 Apple의 공지: https://developer.apple.com/news/?id=05042016a

내용은 아주 간단하게도 IPv6 Only 네트워크에서도 App이 정상적으로 동작을 해야 한다는 것입니다. 이는 IPv4에 기반한 API의 작동은 되지 않는다는 것을 의미합니다. 일반적으로 네트워크 통신 시, NSURLSession과 CFNetwork 같은 High Level API의 경우는 이미 IPv6에 대한 지원에 문제가 없으나, Low-Level socket APIs를 직접 사용할 경우에는 구조체와 함수 등 IPv4 전용 함수를 사용하고 있는지에 대해서 확인이 필요합니다.

또한 앱에서 네트워크 통신 시, 하드 코딩 된 IPv4 주소를 사용하거나, 또는 서버에서 전달해주는 주소가 IPv4 주소를 사용하여 서버에 접근할 때도 앱에 대한 수정이 필요합니다.

따라서 아래에 기술한 방법과 같이 테스트 환경을 구축하여, 정상적으로 네트워크 통신이 가능해야 합니다.

IPv6 테스트 방법

일반적으로는 IPv6 Only 네트워크 환경을 갖추고 테스트를 할 수가 없을 것이기 때문에 Apple에서는 IPv6 테스트를 위하여 NAT64/DNS64 환경을 구성할 수 있도록 가이드를 마련해주었습니다.

테스트 환경

2.png
[https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW16] 에서 발췌

테스트 환경을 구축하기 위해서는 아래와 같은 장비가 필요합니다.

  1. 유, 무선 지원하는 MacOS가 설치된 장비
  2. iPhone, MacOS 장비

MacOS장비의 경우 DNS64, NAT64 역할을 하여 연결된 iOS Device에 IPv6주소를 할당하고, 외부 네트워크(IPv4)와의 통신을 할 수 있도록 해줍니다. (NAT64는 IPv6와 IPv4 호스트들 간에 통신을 할 수 있도록 하는 기술이며, DNS64는 DNS 서버에 AAAA 레코드를 요청했을 때, A 레코드만 존재한다면 A 레코드로부터 AAAA 레코드로 합성(변환)을 해주어서 요청한 서버의 IP주소를 획득할 수 있도록 합니다.)

iPhone은 인터넷 공유(NAT64)를 활성화 시킨 iMac(위의 1항목을 충족한다면 다른 장비도 가능)의 장비에 접속하며, iMac은 유선랜으로 기존 인터넷 환경에 접속하면 됩니다.

따라서 iPhone은 NAT64 환경에서 제공하는 IPv6 주소를 할당 받게 됩니다. 자세한 사항은 아래의 링크를 참고하시면 됩니다.

[https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW16]

만일 위와 같은 방법으로 테스트 시에 네트워크 통신이 제대로 되지 않는다거나, 오동작하는 경우가 발생한다면, 아래의 케이스에 대한 확인이 필요합니다.

  1. IP literal을 직접 hard-coding하여 프로그램에서 사용하고 있는지? 또는 IP Address를 설정파일이나 서버로부터 획득하여 socket연결을 시도하는지?
  2. Network Preflight(통신 전, Wi-Fi, Cellular 등의 연결 테스트)를 ZeroAddress (0.0.0.0)으로 Reachability Test를 하는지?
  3. Low-Level Networking API들을 사용하는지 (소스코드 및 외부 라이브러리)
  4. IP Address를 저장하기 위하여 uint32_tin_addrsockaddr_in과 같은 변수 타입(32bit 이하의 크기)을 사용하는지?

다음 항목에서는 위의 내용에 대해서 좀더 자세히 살펴보도록 하겠습니다.

개발자들이 주의해야 할 사항

IP literal을 프로그램 상에 Hard-Coding한 경우

일반적으로는 IP literal을 직접 사용하는 경우는 없겠지만, 일부 시스템의 경우, 최초 서버에 접근한 후, 해당 서버에서 IP를 할당 받아 다시 할당 받은 IP로 접속하게 하는 시스템들이 있을 수 있습니다. 또는 설정파일에서 IP를 가져와서 사용하는 경우도 있을 수 있습니다. 이럴 경우에는 IPv6 only 네트워크 상에서는 통신이 정상적으로 이루어지지 않으며, Apple 검수 시 Reject 사유가 됩니다. 따라서 반드시 DNS를 이용하여 IP를 획득할 수 있도록 해야 합니다.

Network Preflight를 할 경우

iPhone이나 iPad등 Mobile Device에서는 네트워크 통신이 항상 연결되어 있다고 보장을 할 수 없기 때문에, 통신 전에 Wi-Fi나 Cellular 연결 상태를 확인한 뒤, 통신을 하도록 구현을 많이 하는데요. 이 때, 기존에는 Zero-Address (0.0.0.0)로 Reachability Test를 많이 사용했습니다.

하지만 IPv6 Only 네트워크의 경우에도 Zero-Address로 Reachability Test를 할 경우 정상적으로 연결 상태를 확인할 수 없습니다.
따라서 아래와 같이 변경이 필요합니다.

일반적으로 IPv4 네트워크 환경에는 아래의 API에 Zero-Address를 할당하여 연결테스트를 했습니다.

SCNetworkReachabilityCreateWithAddress()

IPv4및 IPv6 네트워크 환경을 동시에 지원하기 위해서는 아래의 API를 통하여 실제 DNS에 존재하는 Host명을 기입하여 연결테스트를 하도록 해야 합니다.

reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, @"www.google.com" UTF8String]);

SCNetworkReachabilityCreateWithName() 함수를 통하여 연결테스트를 할 때 실제 해당 Domain을 가지고 있는 서버로의 연결상의 부하는 발생하지 않으며, 네트워크 연결 상태만 확인합니다.

Low-Level Networking API들을 사용하는 경우

iOS Foundation Framework에서 지원하는 High-Level API들만을 사용하여 통신을 한다면 별도의 처리는 필요가 없지만, 일반적으로는 Websocket등의 통신을 위하여 외부 라이브러리를 사용하거나, 통신성능을 높이기 위하여 Open Source 네트워크 라이브러리를 사용하는 경우가 있습니다. 이럴 때는 Open Source 상에서 아래와 같은 함수들 만을 사용하고 있는지 확인해야 합니다.

아래와 같은 IPv4 전용 API들이 있다면 확인하여 제거(또는 변경)이 필요합니다.

  • inet_addr()
  • inet_aton()
  • inet_lnaof()
  • inet_makeaddr()
  • inet_netof()
  • inet_network()
  • inet_ntoa()
  • inet_ntoa_r()
  • bindresvport()
  • getipv4sourcefilter()
  • setipv4sourcefilter()

IPv4 타입을 사용하는 부분이 있다면 IPv6 타입도 똑같이 지원을 해야 합니다.

IPv4IPv6
AF_INETAF_INET6
PF_INETPF_INET6
struct in_addrstruct in_addr6
struct sockaddr_instruct sockaddr_in6
kDNSServiceProtocol_IPv4kDNSServiceProtocol_IPv6

IPv6 로 인한 App Reject 사례와 참고 자료

App Reject 사례

일부 앱에서 6월 1일 이후에 검수를 올린 App에서 별다른 변경사항 없이 Reject를 당하는 경우가 발생하였으며, Review Reject 사유에서는 IPv6 only network에서 정상적으로 게임이 실행되지 않는다는 이유를 듣게 되었습니다.

게임과 게임 서버의 통신상에서는 이미 IPv6를 지원하는 API를 사용하도록 조치하고 앱에서 사용하는 모든 서버의 주소를 Domain을 등록하도록 변경하여 문제 없이 검수를 통과할 수 있을 것으로 생각했지만, 위에 말씀 드린 것과 같이 정상적으로 검수를 통과하지 못했습니다. 확인 결과로는 서버로부터 IPv4 주소를 받아서 클라이언트가 그 주소 기반으로 접속을 시도하는 중에 이슈가 문제가 발생하였으며, 해당 주소가 IPv4 literal로 구성되어 있어서, IPv6 only network 환경에서는 정상적으로 Connection을 맺을 수 없는 상황이었던 것입니다.

최근에는 앱을 개발할 때 Open Source나 외부솔루션을 많이 사용하고 있는 추세이기 때문에, 앱에서 사용하고 있는 외부 솔루션에 대해서 IPv6에 대해서 지원이 되는지 명확히 확인해야 할 필요성이 있습니다.

참고 자료





출처 : http://meetup.toast.com/posts/91


XCode에서 iOS App을 Archive 후 Upload to App Store 할 때,


(ERROR ITMS-90023: "Missing required icon file. The bundle does not contain an app icon for iPad of exactly '167x167' pixels, in .png format .")


이와 같은 에러로 인해 업로드 실패하는 경우가 생긴다면


해결 방법!




저기 iPad Pro App iOS 9 83.5pt 부분이 비어있을텐데

167x167 짜리 App Icon을 하나 만드셔서 저 부분에 드래그 & 드랍 해주시면 됩니다!



최근에 Apple에서 출시한 iPad Pro 때문에 생긴 문제같네요.





XCode로 디바이스에 Build & Run 시에


process launch failed: failed to get the task for process 915


와 같은 에러가 발생한다면


Project -> Build Settings -> Code Signing -> Code Signing Identify -> Release 항목을


Developer 용으로 변경하면 해결됩니다.




이 내용은 XCode로 iOS App을 앱 스토어에 업로드 시 발생하는 

아래 error에 대한 해결 방법이기도 합니다.


(ERROR ITMS-90086)




-------------------------------------------------------------------------------------------------------------



출처 : http://www.econovation.co.kr/ecnvb/ios-%EA%B0%9C%EB%B0%9C%ED%8C%81-32bit%EB%A1%9C-%EA%B0%9C%EB%B0%9C%EB%90%9C-%EC%95%B1%EC%9D%84-64bit%EB%A1%9C-%EB%B3%80%ED%99%98-%EB%B0%A9%EB%B2%95/



애플이 아이폰5S 부터 A7 64비트 CPU를 탑재하면서 소프트웨어 개발자도 대응에 고심해야 하는 상황이 되었습니다. 또한 2015년부터는 32비트와 64비트 모두 지원하도록 앱을 개발해야 앱 심사를 받겠다고 합니다.

애플은 64비트 프로세서를 지원함에 따라 더 고성능의 앱을 더 빠르게 구동할 수 있다고 강조합니다. 애플은 개발도구인 X코드를 통해 32비트 앱을 64비트 앱으로 쉽게 변환할 수 있다고 주장합니다. 과거처럼 유니버셜 바이너리를 지원한다고 한 것입니다.

하지만, 앱을 아이폰5와 아이폰5S 모두에서 구동하게 하려면, 동일한 앱이 두 개의 코드를 갖는 걸 감수해야 합니다. 하드웨어야 OS 차원에서 알아서 판단해 32비트냐 64비트냐를 결정해 주겠지만 기본적으로 앱의 전반적인 용량은 커지게 되는 것입니다.

문제는 여기서 그치지 않습니다. 그 동안 애플의 가이드라인에서 벗어나 개발해왔던 앱 개발자라면 기존 앱을 64비트로 변환하는데 상당한 모험심을 가져야 할 것으로 보입니다. 64비트 앱을 원활히 개발하려면 애플에서 제시한 가이드라인을 엄격히 지켜야 하기 때문입니다.

여하튼 2015년부터 앱 개발 및 수정을 하여 앱 심사를 요청하려면 반드시 32비트와 64비트를 지원 하도록 개발이 되어야 하는 필수 요건이 되었습니다.


64비트 아키텍쳐 지원

iOS 개발팁-32bit로 개발된 앱을 64bit로 변환 방법_01

 

애플이 공식적으로 개발자를 위한 새 문서를 올렸는데, 아이폰5s의 64-bit 앱으로 변환하는 과정을 기술한 것입니다.

- https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html#//apple_ref/doc/uid/TP40013501-CH3-SW1

자 그럼 64비트 변환방법에 대하여 알아보도록 하겠습니다.


64 비트 바이너리 변환 방법

1. Xcode 5.0.1 이상 설치합니다. (최신버젼 Xcode 6.1 설치 권장)
2. 개발 프로젝트를 오픈 합니다.

iOS 개발팁-32bit로 개발된 앱을 64bit로 변환 방법_02

3. 프로젝트 Build Settings -> Architectures 설정
- Architectures Standard architectures (armv7, arm64)
- Vaild Architectures arm64 armv7 armv7s

iOS 개발팁-32bit로 개발된 앱을 64bit로 변환 방법_03

4. 프로젝트 설정에서 iOS Deployment Target 을 iOS 5.1 이상으로 설정합니다.
- iOS 5.1 이하로 설정할 경우 64비트 빌드가 되지 않습니다.

iOS 개발팁-32bit로 개발된 앱을 64bit로 변환 방법_04
5. 프로젝트를 빌드를 합니다.
- 빌드시 컴파일러는 에러와 경고를 발생할 것입니다. 소스코드의 에러와 경고 항목을 Xcode 도움말 가이드를 참조하여 직접 수정해야 합니다.
- 애플이 제공하는 가이드 라인을 참조해서 소스 코드를 수정합니다.
https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html#//apple_ref/doc/uid/TP40013501-CH3-SW1

iOS 개발팁-32bit로 개발된 앱을 64bit로 변환 방법_05

6. 소스코드 수정이 완료되면 64비트 하드웨어(아이폰5S 이상) 단말에서 테스트를 합니다.
7. 앱 Archive 를 생성하여 앱 심사을 위헤 애플에 제출합니다.



출처 : http://cyberx.tistory.com/36


내가 만든 iOS앱을 앱스토어에 배포해보자 - 개발할 앱 연결과 권한


기기를 등록했나요? 
기기를 등록했다면 내가 만들 앱의 최소의 정보와 그에 따른 권한을 연결시켜 주어야 합니다.
먼저,


애플 개발자 사이트에 접속하여 [Identifiers - App IDs] 메뉴로 진입합니다.
위와 같은 목록이 나오는 화면에서 오른쪽 상단 [ + 버튼 ]을 클릭합니다.



앱의 아이디를 기술합니다.
앱의 이름이라고 생각하시면 될것 같습니다.


앱의 번들 아이디를 입력합니다.
단독적인 앱을 만들때 사용합니다. 
하단에 Wildcard App ID 는 여러개의 앱을 하나의 번들 아이디 그리고 * (wildcard) 로 구분지어 사용하고자 할때 선택합니다.
여기서는 blog.test 라는 번들 아이디를 입력하겠습니다.
입력 후, 하단의 [continue 버튼] 을 눌러주세요.



다음 화면에서 최종 확인을 합니다.
[ Submit 버튼 ]을 눌러주세요.



그럼 다시 목록화면으로 넘어가는데 위의 이미지와 같이 등록한 내용이 보이게 됩니다.



자. 다음으로 하게 될것은 방금 만든 앱 정보와 디바이스간의 연결입니다.

[ + 버튼 ] 을 눌러주세요.



저는 테스트 진행할 디바이스와 연결할 것이므로 [ Ad Hoc ]을 선택후 하단 [ Continue 버튼 ]을 클릭합니다.



만약 이전 App Id를 여러개 만들어 놓았다면 어떤 앱을 연결할 것인지 선택하게 됩니다.



그리고 어떤 개발자 계정으로 할 것인지 선택을 하게 되죠.

여러개가 등록이 되나 봅니다. 아마 Enterprize 계정 때문에 선택하는 화면이 존재 하는 듯 합니다.



어떤 기기에서 테스트를 할 것인지 선택하는 화면입니다.
2부에서 등록한 기기의 목록이 보여집니다.
선택이 완료되면 [ Continue 버튼 ] 을 클릭합니다.


완료되었습니다.
위의 이미지에 [ Download 버튼 ]을 클릭하여 1부에서 개발자 인증서를 내려받듯이 맥에 다운로드를 받습니다.
다운로드 받은 profile을 맥에서 더블클릭 하게 되면 맥에서 자동으로 profile을 등록하여 줍니다.

맥북에 개발자 인증을 하고
어떤 기기에서 테스트 할 것인지 기기 등록을 하고
내가 만들 앱을 등록하여 어떤 기기와 연동을 할 것인지에 대하여 알아보았습니다.


이제 방금 등록한 앱의 Bundle ID를 사용하여 앱을 디자인 하면 됩니다.

출처 : http://cyberx.tistory.com/29


내가 만든 iOS앱을 앱스토어에 배포해보자 - 기기 등록


나의 맥북에 내가 너의 개발자다!! 라고 인식시켰다면

다음으로 해야 할 것은 개발할 기기를 등록해야 합니다.


안드로이드와는 다르게 iOS는

기기의 일련정보를 개발자 사이트에 입력해야

내가 작성한 코드를 USB 연결을 통하여 실제 디바이스 테스트가 가능하기 때문입니다.


실제 디바이스 테스트는 개발자 유료 등록을 마쳐야지만 가능합니다.

만약 나의 앱에 인앱결제가 들어간다면 시뮬레이터로는 테스트가 불가능하기 때문에

필히 개발자 유료 등록하여야 합니다.


USB연결말고도 Ad-Hoc으로 여러사람이 웹에서 다운로드 받아 테스트가 가능하지만

이때도 Enterprize 계정이 아닌 이상 테스트할 사람의 모든 기기정보를 입력해야 합니다.

이 부분은 추후 Ad-Hoc 계정 웹으로 다운받아 테스트하기 포스팅에서 자세히 다루겠습니다.




먼저, 애플의 개발자 사이트에 접속합니다. http://developer.apple.com/ 






왼쪽메뉴에서 [Devices - All 혹은 해당하는 기기]를 클릭합니다.




상단 오른쪽 + 버튼을 클릭합니다. 



 

이곳에서 디바이스의 이름과 UDID를 입력합니다.
디바이스의 이름은 다른 기기와 중복되지 않게끔 내가 알아볼수 있는 편한 이름으로 입력합니다.
추후에 다시 변경할 수 있습니다.

등록 해야 할 기기가 여러대인경우
하단의 Register Multiple Devices 항목을 이용하십시오.
애플이 의외로 친절히 샘플파일까지 제공하고 있습니다.


여기서 중요한 것은 UDID 입니다.
이 정보는 피씨의 iTunes 프로그램에서 기기 연동 후에 확인 하실 수 있습니다.

앱스토어에서 UDID를 읽어준다는 앱을 받아서 등록해 봤는데,
결론은 기기 등록은 되나 연결이 되지 않았습니다.
내가 제작한 앱이 기기에 설치가 되지 않아 한참을 원인을 찾느라 은근 시간을 사용했습니다.
원인은 다운받은 UDID 번호 알려주는 앱이 틀린 정보를 알려주고 있었습니다.

혹시나, 앱스토어에서 UDID 앱 검색해서 설치하신 분들은 되도록이면 iTunes를 이용하시길 바랍니다.
그저 정공법이 최고입니다.



iTunes를 연결하고 ①번을 클릭합니다.
클릭하고 나면 ②번을 확일 할 수 있는데, 우리가 필요한것은 UDID 이므로 일련번호를 클릭합니다.
그럼 이 번호가 토글되어 UDID가 나오는데 안나올경우 나올때까지 클릭하시면 됩니다.
번호 위에서 오른클릭을 하면 복사가 가능합니다.

복사된 번호를 좀전의 개발자 페이지의 UDID 란에 입력하고 하단의 Continue 버튼을 클릭합니다.


 


등록하려는 기기의 정보를 확인하고 Register 버튼을 누르면 디바이스 목록 첫화면으로 돌아가며 등록이 완료됩니다.


기기 삭제에 관하여..

 
기기를 삭제하는 것은 개발자 유료 멤버십이 종료되는 시점(1년)에 초기화가 진행된다고 합니다.
그 이전에는 활성화 / 비활성화만 가능하다 합니다.
실제로 목록에서 사라지지 않습니다.


출처 : http://cyberx.tistory.com/8


내가 만든 iOS앱을 앱스토어에 배포해보자 - 개발자 등록


iOS 앱을 제작하고 앱스토어에 배포하기 위한 단계를 여러차례 나누어 포스팅 하려 합니다.



즐겨찾게 될 사이트 


* 애플의 개발자 사이트 https://developer.apple.com/

그리고 어마무시하게 클릭하게 될 메뉴 - 

이곳은 개발자를 등록하고 테스트 기기를 추가하며 개발에 필요한 인증서 등 필요한 정보를 입력하고 제공받는 곳입니다.



* iOS 앱 등록 사이트 https://itunesconnect.apple.com
내가 개발한 앱을 스토어에 올리기 위해 준비하는 사이트.
앱 내의 결재항목을 추가/삭제하거나 앱스토어에서 보여줄 앱의 미리보기 스크린샷 등 앱의 전반적인 정보를 등록하거나 추세를 파악하는 등 어플에 대한 정보를 얻거나 입력 할 수 있습니다.

이 사이트는 애플의 개발자 사이트에서 개발자로 등록한 계정으로 로그인이 가능합니다.

애플 개발자 등록 비용은 1년에 $99 입니다.



1. 맥 개발 인증서 받기

iOS 앱을 개발하기 위해서는 맥이 필요합니다. 제작도구 툴인 xcode가 맥에서만 동작하기 때문입니다.

맥의 [LaunchPad - 키체인 접근]을 실행합니다.

[키체인 접근 - 인증서 지원 - 인증 기관에서 인증서 요청]


사용자 이메일 주소, 일반 이름을 입력하고,

나는 맥에 저장할 것이므로 [디스크에 저장됨]과 [본인이 키 쌍 정보 지정]을 선택 후 [계속]버튼을 클릭합니다.

어디로 다운로드 받을 것인지 위치를 지정해주는 창이 나오는데 위치 지정 후 [저장] 버튼 클릭을 하게 되면 그 위치에 방금 요청한 인증서(CertificateSinging...)가 다운로드가 되어 저장이 됩니다. 



2. 맥 개발 인증서 등록하고 iOS개발 인증서 받기

애플의 개발자 사이트 https://developer.apple.com/ - Member Center - Certificates, Identifiers & Profiles 클릭



Certificates 선택



새로 등록할 것이므로 [ + ] 버튼 클릭



종류가 많습니다..  

iOS 앱 개발을 위한 인증서며 푸쉬용 인증서며 Passbook, 웹사이트 등 여러가지가 있지만

내가 할 것은 App Store and Ad Hoc 입니다. 앱을 등록하거나 테스트용으로 배포할 수 있는 자격을 주는 인증서입니다.

[Continue - 다음페이지도 Continue] 클릭


Choose File... 에서 아까 맥에서 다운로드 받은 인증서를 등록하고 하단 [Generate] 클릭


이 작업이 완료가 되면 인증서를 다운로드를 할수 있는 페이지로 이동합니다.
이것을 맥에 다운로드받습니다. 

다운로드 받은 인증서를 실행하게 되면 키체인 화면이 활성화되고 목록에 방금 실행한 인증서가 목록에 나타납니다.


개발자 등록은 이렇게 하면 끝입니다.


상당히 쉬운작업인데 단어가 어려워 고생 좀 했습니다...

다음 포스팅에는 내 아이폰을 테스트 기기로 등록해보도록 하겠습니다.


+ Recent posts