Git을 통해 버전 관리를 할 때


Gitignore를 이용하면 특정 파일을 버전 컨트롤에서 제외시킬 수 있습니다.


이는 쓸모없는 파일이나 원하지 않는 파일을 commit에서 제외시켜 merge crash를 예방하기 위함인데요


아래는 Unity 프로젝트의 gitignore 목록입니다.



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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# =============== #
 
# Unity generated #
 
# =============== #
 
Temp/
 
Obj/
 
UnityGenerated/
 
Library/
 
 
 
# ===================================== #
 
# Visual Studio / MonoDevelop generated #
 
# ===================================== #
 
ExportedObj/
 
*.svd
 
*.userprefs
 
*.csproj
 
*.pidb
 
*.suo
 
*.sln
 
*.user
 
*.unityproj
 
*.booproj
 
 
 
# ============ #
 
# OS generated #
 
# ============ #
 
.DS_Store
 
.DS_Store?
 
._*
 
.Spotlight-V100
 
.Trashes
 
Icon?
 
ehthumbs.db
 
Thumbs.db
 
GraphicsSettings.asset
 
ProjectSettings.asset
 
ProjectVersion.txt
cs


유니티 프로젝트 루트 폴더안에 


.gitignore 라는 파일을 만들고





위 Text를 복사하여 붙여넣고 저장합니다.


그리고나면 Unity에서도 git을 무리없이 사용할 수 있습니다.



이번에는 Unity 프로젝트에 Unity Ads를 연동해보겠습니다. (매우 간단 주의)



우선 Unity에서 [Window -> Services] 하면 인스펙터 뷰 옆에 아래와 같은 화면이 나타나는데


Ads 항목이 OFF(디폴트)로 되어있는 것을 볼 수 있습니다.





Ads 항목을 클릭하면 아래와 같이 나오는데


토글 버튼을 눌러 비활성화되어있는 Ads를 활성화 시킵니다.





13세 미만 아이들에게 지도감독이 필요한 앱인지 여부를 설정하고 Continue 합니다.





활성화가 완료되면 아래와 같이 나옵니다.


원하는 Platform을 체크합니다.


Enable test mode를 체크하면 유니티에서 제공하는 짧은 테스트 광고영상만 송출됩니다.


(런칭 시 반드시 위 항목 체크를 해제할 것)





여기까지 완료했다면, 


using UnityEngine.Advertisements; 


를 할수있게 됩니다!


UnityAdsHelper라는 C# 스크립트를 하나 생성하고


아래의 코드를 복사해서 붙여 넣습니다.


그 다음, 빈 게임 오브젝트를 하나 생성하고 UnityAdsHelper.cs를 AddComponent 해줍니다.



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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using UnityEngine;
using UnityEngine.Advertisements;
 
public class UnityAdsHelper : MonoBehaviour
{
    private const string android_game_id = "xxxxxxx";
    private const string ios_game_id = "xxxxxxx";
 
    private const string rewarded_video_id = "rewardedVideo";
 
    void Start()
    {
        Initialize();
    }
 
    private void Initialize()
    {
#if UNITY_ANDROID
        Advertisement.Initialize(android_game_id);
#elif UNITY_IOS
        Advertisement.Initialize(ios_game_id);
#endif
    }
 
    public void ShowRewardedAd()
    {
        if (Advertisement.IsReady(rewarded_video_id))
        {
            var options = new ShowOptions { resultCallback = HandleShowResult };
 
            Advertisement.Show(rewarded_video_id, options);
        }
    }
 
    private void HandleShowResult(ShowResult result)
    {
        switch (result)
        {
            case ShowResult.Finished:
                {
                    Debug.Log("The ad was successfully shown.");
 
             // to do ...
             // 광고 시청이 완료되었을 때 처리
 
                    break;
                }
            case ShowResult.Skipped:
                {
                    Debug.Log("The ad was skipped before reaching the end.");
 
             // to do ...
             // 광고가 스킵되었을 때 처리
 
                    break;
                }
            case ShowResult.Failed:
                {
                    Debug.LogError("The ad failed to be shown.");
 
             // to do ...
             // 광고 시청에 실패했을 때 처리
 
                    break;
                }
        }
    }
}
 
cs



위 코드는


ShowRewardedAd() 함수로 비디오 광고 송출 요청을 하고


HandleShowResult 콜백으로 요청 결과에 따라 Finished, Skipped, Failed 처리하는 구조로 되어있습니다.


* 여기서 androiod game id와 ios game id 그리고 rewarded video id가 필요한데


Services의 우측 상단에 있는 Go to Dashboard 를 누르면





아래와 같은 화면이 뜨는데


여기서 android 게임 ID와 ios 게임 ID를 확인할 수 있습니다.





UnityAdsHelper.cs의 android_game_id 변수와 ios_game_id 변수에 Game Id 숫자 7자리를 각각 넣어주시면 됩니다.


그 다음, 구글 플레이 스토어 또는 애플 앱 스토어 플랫폼을 클릭하여 Ad placements 정보를 확인합니다.





기본적으로 Video와 Rewarded Video 두 가지가 생성되어있는데


첫 번째에 있는 Video는 Skip이 가능한 광고이고


두 번째에 있는 Rewarded Video는 Skip이 불가능한 보상형 광고입니다. 


수익을 많이 내려면 당연히 Skip이 불가능한 보상형 광고를 써야겠죠?


위 스크린샷 처럼 Rewarded Video를 Enabled 하고 Default로 설정합니다. (우측에 EDIT 버튼으로 세부설정이 가능함)


그리고 Rewarded Video의 PLACEMENT ID를 복사하여


UnityAdsHelper.cs의 rewarded_video_id 변수에 넣어줍니다.



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



자, 모든 준비가 끝났습니다!


Unity Editor에서 ShowRewardedAd()로 광고를 요청했을 때 아래와 같은 화면이 나온다면


정상적으로 연동된 것입니다.





이제 원하는 상황에 ShowRewardedAd() 함수를 호출하고 (주로 게임 오버될 때 혹은 특정 버프를 받을 때)


HandleShowResult 콜백에서 원하는 처리를 하여 마무리해줍니다. (캐릭터 부활 혹은 버프효과 적용 등)





Fab Lab Seoul과 서울 디자인재단 주최로 진행된 [2016 패션웨어러블 메이커톤]에 

개발자로 참가했었습니다.

옷에 달린 단추를 누르거나 소매에 달린 슬라이더를 조절하여 

스마트폰 뮤직플레이어를 컨트롤하는 웨어러블 디바이스를 개발하는 것이 저희 팀의 목표였고

옷과 스마트폰의 사이에 블루투스 통신할 수 있는 뮤직플레이어 App을 만드는 것이 제 역할이였습니다.



여기서 

▶MAKE A THON 이란? 

의상 제작이 가능한 패션 디자이너와 기획자, 개발자, 2D/3D 디자이너 등 다양한 분야의 메이커들이 팀을 이루어 사전행사와 무박2일의 본행사동안 “패션 웨어러블”을 주제로 Ideation부터 Prototyping 까지 진행하는 메이킹 마라톤입니다.



제가 만든 간단한 뮤직플레이어 App을 소개해드리겠습니다!



Unity3D로

 - 플레이리스트

 - 음악 재생/정지

 - 볼륨 조절

 - 재생 위치 조절


등의 기능이 구현된 간단한 뮤직플레이어를 만들었는데요.

그 중에, 현재 재생되고 있는 음악의 강약을 옷에 달린 LED에 그대로 표현해주기 위해 비쥬얼라이저를 구현했습니다.

화면 가운데에는 PointLight가 있고 하단에는 막대 그래프가 있는데

영상에서 보이는 것 처럼 재생 중인 음악의 세기에 따라 PointLight의 밝기가 반응하고 하단의 막대그래프도 요동치게끔 하였습니다.


이처럼 AudioListener.GetOutputData() 함수를 이용하면 사운드 비쥬얼라이저를 쉽게 구현할 수 있습니다.


https://docs.unity3d.com/ScriptReference/AudioListener.GetOutputData.html



아래는 코드의 일부입니다.



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
37
38
39
40
41
42
43
44
using UnityEngine;
using System.Collections.Generic;
 
public class Visualizer : MonoBehaviour
{
    public List<UISprite> target_sprites;
 
    public Light pointLight;
 
    public int detail;
    public float amplitude;
    public float intensityFactor;
 
    private float baseIntensity = 0.1f;
 
    void Update()
    {
        GetOutputData();
    }
 
    private void GetOutputData()
    {
        float[] data = new float[detail];
        float packagedData = 0.0f;
 
        AudioListener.GetOutputData(data, 0);
 
        for (int i = 0; i < data.Length; ++i)
        {
            packagedData += Mathf.Abs(data[i]);
        }
 
        float resultHeight = packagedData * amplitude;
        float resultIntensity = baseIntensity + packagedData * amplitude;
 
        for (int i = 0; i < target_sprites.Count; ++i)
        {
            target_sprites[i].height = (int)(resultHeight * ((i + 1* 0.4f));
        }
 
        pointLight.intensity = (baseIntensity + packagedData) / (detail / intensityFactor);
    }
 
}
cs


여기서 target_sprites 는 아래의 5개 막대를 담은 변수이고

AudioListner.GetOutputData()로 추출된 데이터(packagedData)를 통해 막대그래프의 height와 PointLight의 밝기를 조절하는 코드입니다.




아래는 메이커톤 당시 시연영상입니다~



영상 초중반 부는 팀원의 프로젝터 맵핑 연출이고 후반부 조금은 음악에 LED가 반응하는 모습을 짧게! 볼 수 있습니다.

시연 영상을 제대로 찍지 못해서 아쉬움이 많이 남네요 ㅠㅠ


개발자를 힘들게 하는 애플의 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


해상도 목록

해상도화면비율삼성LG애플구글
320 x 4802:3옵티머스1아이폰3
480 x 8003:5갤럭시S1
갤럭시S2
넥서스S
넥서스One
640 x 9602:3아이폰4
640 x 11369:16아이폰5
720 x 12809:16갤럭시S2 HD
갤럭시S3
갤노트2
옵티머스G갤럭시넥서스
750 x 13349:16아이폰6
아이폰6S
아이폰7
768 x 10243:4옵티머스뷰아이패드1
아이패드2
아이패드미니
768 x 12803:5넥서스4
800 x 128010:16갤럭시탭10.1
갤노트1
G패드10.1넥서스7
1080 x 19209:16갤럭시S4
갤럭시S5
갤노트3
옵티머스G프로
G2
아이폰6+
아이폰6S+
넥서스5
Pixel
1200 x 192010:16G패드8.3넥서스7(2013)
1242 x 22089:16
1440 x 25609:16갤럭시S6
갤럭시S7
갤노트4
갤노트5
갤노트7
G3
G4
G5
V10
V20
Pixel XL
1536 x 20483:4아이패드미니레티나
아이패드에어2
1600 x 256010:16갤럭시탭S
갤럭시노트10.1(2014)
갤럭시노트프로12.2
넥서스10
2048 x 27323:4아이패드프로


화면비율

  • 스마트폰 대세는 9:16
  • 스마트패드 대세는 10:16(안드로이드), 3:4(애플)
  • 아래표는 아래로 갈수록 길쭉
화면비율추세대표사례
3:41536 x 2048(아이패드3, 아이패드4)
2048 x 2732(아이패드프로)
2:3640 x 960(아이폰4)
320 x 480(아이폰3, 옵1)
10:16★★1600 x 2560(갤탭S, 넥10)
1200 x 1920(G패드8.3, 넥7)
3:5768 x 1280(넥4)
480 x 800(갤1, 갤2, 넥S, 넥원)
9:16★★★1440 x 2560(갤6, 갤7, 갤노4, 갤노5, G3, G4, G5, 픽셀XL)
1080 x 1920(갤4, 갤5, 갤노3, 옵G프로, G2, 넥5, 아이폰6, 픽셀)



출처 : http://zetawiki.com/wiki/%EC%8A%A4%EB%A7%88%ED%8A%B8%ED%8F%B0_%ED%95%B4%EC%83%81%EB%8F%84,_%ED%99%94%EB%A9%B4%EB%B9%84%EC%9C%A8


+ Recent posts