카테고리 보관물: iOS

Xcode 에서 Pod 프로젝트의 경고 표시 없애기

Xcode를 이용해 개발을 하다보면 cocoapod를 이용해 외부 라이브러리를 사용하게 되는데요. Swift 언어가 계속해서 발전하다보니 새로운 버전에서 deprecated 되는것들이 많아져서 1년만 지나도 꽤 많은수의 경고문구를 보게 됩니다. 내 프로젝트의 경우 소스코드를 직접 수정하면 되지만 외부 라이브러리들은 해당 프로젝트의 상황에 따라서 경고되는 항목들을 고치지 못하는 경우가 많습니다.

이렇게 되면 어느순간부터 내 프로젝트의 빌드 경고창에는 외부 라이브러리들의 경고가 많아져서 내 프로젝트의 경고가 묻히고 수정해야 된다는 사실을 인지하지 못하게됩니다.

위의 경우 총 58개의 경고가 있는데 이중 56개는 외부 라이브러리들의 경고표시입니다. 내 프로젝트의 경고표시는 제일 아래쪽에 2개가 위치합니다. 또한 경고문구는 기본으로 펼쳐져 있어서 스크롤을 아래까지 해야 겨우 볼 수 있습니다. 프로젝트가 커져서 사용하는 외부 라이브러리가 많아지면 경고는 300개를 넘는경우도 있습니다.

다행히도 이 문제를 해결할 방법이 있습니다. cocoapod의 경우 Podfile에 아래 내용을 추가해서 Pod 프로젝트들에 대해 경고가 표시되지 않도록 설정 할 수 있습니다.

inhibit_all_warnings!

전체 Podfile 의 샘플을 보면 다음과 같은 식입니다.

platform :ios, '9.0'
target 'MyProject' do
  use_frameworks!
  inhibit_all_warnings!
  pod 'Alamofire', '~> 4.5'
end

전체 Pod이 아닌 특정 Pod의 경고만 표시하지 않으려면 pod 선언할때 옵션으로 선언합니다.

pod 'Alamofire', '~> 4.5', :inhibit_warnings => true

Podfile 을 수정하고 pod install 을 다시 실행한후 Xcode 프로젝트에서 빌드를 다시하거나 클린빌드를 하면 기존에 보이던 Pod 프로젝트의 경고표시가 모두 사라진것을 볼 수 있습니다.

이 옵션은 pod init 으로 Podfile을 처음 생성할때 기본으로 들어가면 좋을것 같은데 기본 옵션은 아닙니다.

유튜브

달구지 코딩이라는 유튜브 채널을 만들어서 운영중입니다. 이 포스트 내용은 아래 유튜브 영상에서도 확인할 수 있습니다. 유튜브 구독 부탁드려요 ^^

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

iOS 삽질 할뻔 : Xcode 9.2로 업그레이드하면 앱스토어 업로드 불가

최근 들어 애플의 소프트웨어 버그가 자주 발생해서 말이 많은데 오늘은 개발자들이 macOS, iOS 개발할때 꼭 사용해야하는 Xcode에 심각한 버그가 발생했습니다.

12월 5일(화)에 iOS 11.2 SDK를 포함한 Xcode 9.2 버전이 새로나왔는데요. 이 버전으로 업그레이드후 열심히 개발하는데까지는 좋은데 앱스토어에 앱을 업로드 하려고 하면 오류와 함께 실패한다고 합니다.

2017년 12월 6일(수) 기준으로는 이 문제가 발생하지 않습니다.

아래와 같은 오류가 발생한다고 하는데요. 정식출시된 Xcode 인데 잘못된 버전으로 인식해서 앱스토어에 업로드 할 수 없는 버그가 발생한거죠 ㅜㅜ

ERROR ITMS-90534: "Invalid Toolchain. New apps and app updates must be built with the public (GM) versions of Xcode 6 or later, macOS, and iOS SDK or later. Don't submit apps built with beta software including beta macOS builds."  

해결 방법은 Xcode 9.2를 완전히 지우고 앱스토어가 아닌 애플 개발자 센터 홈페이지에가서 Xcode 9.1 버전을 직접 다운로드 받아서 설치해야 합니다. Xcode 용량이 10기가 정도 했던거 같은데… 인터넷이 느린 저희 집이라면 근처 스타벅스 가서 받아야겠네요.

이 게시글의 제목이 삽질이 아니라 삽질할뻔인 이유는 저는 영향을 받지 않았기 때문입니다!!! 오늘 오전에 Xcode 9.2 업데이트도 했고 앱스토어에 업로드도 했지만 저는 빌드는 bitrise.io 라는 서비스를 사용하고 있기 때문에 영향이 없었습니다. bitrise.io 에서는 여러가지 버전의 Xcode를 가지고 있고 원하는 Xcode 버전만 변경하면 되서 이번 영향에서 벗어날수 있었습니다! bitrise.io 적용한지 몇주 안됬는데 ㅎㅎ 운이 좋았네요.

이 포스트의 bitrise.io 링크를 눌러서 가입하시면 제 무료범위의 빌드 시간이 늘어나는 혜택이 주어집니다! 기본은 10분인데 조금씩 늘어나고 5명이 되면 티셔츠 받을수 있어요!

조만간 시간이 되면 bitrise.io 서비스에 대해서도 글을 적을게요. 개인적으로는 bitrise.io를 빌드 하는데 사용하고 있는데 여러가지 서비스중에 제일 마음에 들었어요. Xcode 베타 버전도 빠르게 지원합니다. 회사에서는 유료 계정으로 사용중입니다.

참고정보

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

iOS 삽질 : 스토리보드만 열면 Xcode가 죽음

Xcode 9으로 업그레이드 하고나서 개발을 시작하려고 하는데 Storyboard 혹은 xib 파일만 열면 Xcode가 종료되서 개발을 할 수 없는 상황이 발생했습니다.

크래시 로그중 일부는 다음과 같이 표시됩니다.

ProductBuildVersion: 9B55
ASSERTION FAILURE in /Library/Caches/com.apple.xbs/Sources/IDEFrameworks/IDEFrameworks-13532/IDEKit/Application/IDEDocumentController.m:2223
Details:  There can only be one document registered with a given URL. newDocument:<IBStoryboardDocument: 0x7fcba0fc7000>(  0   -[IDEEditorDocument init] (in IDEKit)
  1   -[IBDocument init] (in IDEInterfaceBuilderKit)

혹은 다음과 같은 에러

ProductBuildVersion: 9B55
ASSERTION FAILURE in /Library/Caches/com.apple.xbs/Sources/IDEInterfaceBuilder/IDEInterfaceBuilder-13529/InterfaceBuilderKit/IssueProvider/IBIssueProvider.m:72
Details:  castedInstance should be an instance inheriting from IBDocument, but it is IDEPegasusSourceEditor.SourceCodeDocument

프로젝트는 아무것도 수정한적이 없고 그저 Xcode 9을 오랫만에 열었을 뿐인데 이런 오류가 발생해서 당황스러웠습니다.

이런 저런 글을 보면 소스코드 편집기로 열어서 nil key 라고 된걸 지워라 Tab Bar Item 관련된걸 지우라는둥 여러가지 이야기가 있었지만 모두 동작하지 않았습니다. 그리고 제 상황에서는 모든 xib, 스토리 파일이 열리지 않았기 때문의 위의 해결 방법들은 해당하지 않았을것 같았죠.

해결 방법은 간단합니다.

Xcode 에서 CMD + Shift + O 키를 눌러서 스토리보드 파일이나 인터페이스 빌더 파일을 열면 Xcode가 종료되지 않고 정상적으로 실행됩니다 =_=/ 한번 열리고 나면 다른 모든 스토리보드나 인터페이스 빌더 파일을 열어도 오류없이 잘 열립니다. 네비게이터에서 스토리보드를 여는거에 문제가 있나봅니다.

삽질이란 다 이런식으로 끝나는거죠 뭐

참고정보

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

iOS 삽질 : iOS 11에서 SearchBar 높이 변경 이슈

iOS 11에서 UISearchBar의 높이가 기존 44에서 56으로 변경되었습니다. 대부분의 경우 큰 문제는 없지만 네비게이션바와 함께 사용하는 경우 높이 변경으로 인해 문제가 발생했습니다.

네비게이션바의 titleView에 UISearchBar를 사용하는 경우 네비게이션바의 높이인 44를 넘어가게 되어 검색이후의 화면에서 네비게이션바 하단에 검정색 공백이 생기는 문제가 있었는데요.

현상

아래 개발화면의 스샷은 왼쪽의 첫번째 화면의 네비게이션바에 UISearchBar가 있고 두번째 화면이 검색결과를 눌렀을때 이동하는 화면입니다.

첫번째 화면과 두번째 화면의 네비게이션 바의 높이가 달라진것을 볼 수 있고 이로 인해 두번째 화면의 네비게이션바 하단에 검정색 공백이 추가됩니다.

이는 앞서 이야기 했던 UISearchBar의 높이가 44에서 56으로 변경된것에 따른 영향으로 첫번째 화면에서는 네비게이션바의 높이가 UISearchBar의 높이에 맞게 56으로 늘어났고 두번째 화면에서는 이전화면의 높이인 56픽셀보다 적은 44픽셀의 네비게이션바를 보여주면서 12픽셀 만큼의 검정색 공백이 생기는 문제입니다. iOS에서 똑똑하게 변경해주면 되는데 이게 처리가 안되더라구요.

해결

우선 첫번째 실패한 해결방법은 SearchBar의 높이를 44로 강제 설정하는것입니다. frame 정보를 변경하는것으로는 안되고 heightAnchor 값을 설정해줘야합니다. 아래 코드를 적용합니다.

if #available(iOS 11.0, *) {
    searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
}

이렇게 하면 높이가 44로 잘 변경되지만 UISearchBar에 글자를 입력하기위해 포커스를 가져가면 UISearchBar가 살짝 내려오는 문제가 생깁니다. 이 문제는 어떻게 해결할 방법이 없더라구요 ㅜㅜ

살짝 내려오니까 내가 뭔가를 수정하면 되겠구나 싶어서 삽질을 계속해서 해봤지만 무슨수를 써도 안되더라구요 ㅜㅜ

최종적으로 해결한 방법은 UISearchBar를 감싸는 UIView를 하나 만들고 이 뷰의 frame 값을 강제로 지정하는 것입니다.

class SearchBarContainerView: UIView {
    let searchBar: UISearchBar
    init(customSearchBar: UISearchBar) {
        searchBar = customSearchBar
        super.init(frame: CGRect.zero)
        addSubview(searchBar)
    }

    override convenience init(frame: CGRect) {
        self.init(customSearchBar: UISearchBar())
        self.frame = frame
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        searchBar.frame = bounds
    }
}

let searchBarWrapper = SearchBarContainerView(customSearchBar: searchBar)
searchBarWrapper.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44)
navigationItem.titleView = searchBarWrapper

이렇게 하면 해결! 첫번째 방법이 깔끔하고 정석대로 해결하는것 같은데 제대로 동작하지 않으니 두번째 방법을 사용할 수 밖에 없었습니다. iOS 개발하다 보면 이런식으로 해결해야 하는 경우가 있더라구요.

삽질지수

이번 삽질의 삽질 지수는 1입니다. (삽질지수 범위 1 5 단계) 처음부터 원인을 알고 있었고 해결방법만 찾으면 되는데 인터넷에 있는 방법중에 되는게 있어서 다행이었죠.

이거 때문에 하루가 그냥 사라졌네요 ㅜㅜ 첫번째 방법으로 깔끔하게 해결하려고 계속 삽질 했던게 원인이었어요. 그래도 해결할 수 있어서 다행이었어요. 해결하지 못하면 네비바 아래에 검색바를 위치시켜야되서 내키지 않았거든요.

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

iOS 삽질 : 인터페이스 빌더에서 설정한 색상이 제대로 표시 안됨

인터페이스빌더(interface builder) 혹은 스토리보드(storyboard)에서 디자이너간 준 색상 코드를 입력했는데 이상하게 코드로 입력한 색상과 다르게 보이는 현상이 있었습니다.

코드로 입력한건 잘되는데 인터페이스 빌더에서 직접 지정한 색상의 경우에만 원하는 색상이 표시되지 않았죠. 그래서 찾다 보니 Color Space 의 문제임을 알게 되었습니다.

이거는 맥에서 애플이 제공하지 않는 모니터를 사용할때 Picker 를 이용해서 색상을 선택하면 나오는 문제랑 비슷한데요. 같은 색상 코드라고 해도 Color Space 에 따라서 다르게 표현되는거죠.

하지만 저는 Xcode 에서 Generic RGB를 맞게 설정하고 hex 코드를 입력했음에도 원하는 색상이 표시되지 않았습니다.

xcode 색상 선택기

xcode 색상 선택기

그래서 혹시나 Xcode 가 저기에 지정한 Color Space 를 무시하고 자기 맘대로 하는건 아닐까 싶어서 인터페이스 빌더 파일을 소스보기로 봤더니 역시나 Color Space 를 자기 마음대로 지정하고 있었습니다. Generic RGB 가 당연히 일반 RGB 스페이스라고 생각했는데 이건 애플의 버그 아닌가 싶어요…

- <color key="textColor" red="0.45098039215686275" green="0.4823529411764706" blue="0.51764705882352935" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="textColor" red="0.45098039215686275" green="0.4823529411764706" blue="0.51764705882352935" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>

위 코드의 윗부분은 색상이 잘못 나올때 이고 아랫 부분은 색상이 제대로 나올때 입니다. 보면 colorSpace 값이 calibratedRGB으로 지정 되었을때 색상이 잘못나오는것을 볼 수 있습니다.

그래서 colorSpace 는 custom 으로 변경하고 customColorSpace 를 sRGB로 변경해서 원하는 색상을 표현 할 수 있게 되었습니다.

검색하다보니 Xcode 8에서는 제가 변경한걸로 기본 스페이스가 바뀌었다는데 이상하게 새로 만든 파일에서 계속 이런식으로 적용되더라구요. 이거 때문에 디버깅 뷰 까지 열어가면서 색상 코드 디버깅 하기는 처음이었습니다.

전체 프로젝트에서 저런식으로 잘못 표시된 색상이 있을까 싶어 검색해봤더니 어마어마하게 많더군요… 그래서 아래 명령어로 한번에 변경했습니다.

$ grep -rl 'colorSpace="calibratedRGB"' 폴더/* | xargs sed -i '' 's/colorSpace="calibratedRGB"/colorSpace="custom" customColorSpace="sRGB"/g'

이렇게 해도 나중에 또 색상 지정할때 이런 문제가 발생할 수 있는 여지는 있습니다. 그건 바로 Color Picker 에서 색상을 지정해두고 사용했을때 그 색상을 사용하면 색상을 추가할때의 colorSpace 로 다시 변경됩니다. 그래서 저는 이런식으로 기존에 저장해두고 사용하던 색상을 다 덮어 버렸습니다.

색상 피커 저장된 색상 지움 ㅋ

색상 피커 저장된 색상 지움 ㅋ

지우는 방법을 몰라서 그냥 안쓸거 같은 색상으로 덮어 버렸어요.

http://stackoverflow.com/a/27283783 글을 보면 칼라 피커에서 hex 코드를 입력하면 Color Space가 원복된다는 이야기도 있네요… 제 문제도 이 경우에 해당하는것 같아요. 이런식이면 인터페이스 빌더에서 색상입력하지 말라는거나 다름없지 않나요…. RGB 코드 따로 입력하는게 얼마나 귀찮은데

애플의 이 정책은 나름 모니터마다 같은 색상을 보게하려는 의도라고는 하던데 이것 때문에 오히려 원하는 색상을 표시 못하는 경우가 더 많은거 아닌가 하는 생각이 들었습니다.

제가 제대로 이해하지 못하고 삽질을 해결한것 같아서 여전히 찝찝합니다. 더 좋은 방법을 알고 계신분은 댓글로 알려주세요 ~

덧. 아마도 이 문제는 아이맥이나 애플이 만든 모니터를 사용한다면 발생하지 않을것도 같아요. 색상 피킹하는 툴은 아이맥이나 애플이 만든 모니터에서는 괜찮았거든요…

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

iOS 삽질 : 릴리즈 빌드에서만 런타임에 에러 발생

앱을 만들다가 Debug 에서 잘 실행되는것을 확인하고 TestFlight 에 올려서 테스트 하는데 앱을 시작하자 마자 크래시가 발생하는 문제가 발생했습니다.

발생한 에러는 다음과 같았습니다

2017-04-03 15:12:19.049 daangn[48068:1047076] Unknown class _TtC6daangn17NotificationTabVC in Interface Builder file.
Could not cast value of type 'UIViewController' (0x112194288) to 'daangn.NotificationTabVC' (0x10bdc09c8).

이렇게 저렇게 해결 방법을 찾다보니 Swift 의 Release Scheme의 Optimization Level 을 ‘Fast, Whole Module Optimization’ 에서 None 으로 변경하면 잘된다는 글을 발견하고 그대로 해봤더니 정말이지 Release scheme 에서도 에러가 발생하지 않았습니다.

좀더 정확히는 ‘Fast, Whole Module Optimization’ 이 아닌 ‘None’, ‘Fast, Single-File Optimization’ 로 변경하면 앱이 종료되지 않았습니다.

Optimization 의 버그 인가 싶어서 에러 메시지에서 못찾는다고 나온 클래스만 별도의 IB 로 분리하거나 스토리보드로 분리해보고 Derived Data 도 지우고 Clean Build 도 해봤지만 문제는 해결되지 않았습니다.

이렇게 하루내내 삽질을 하다가 원인을 찾았는데 그건 제가 사용하는 라이브러리의 문제 였습니다. 저는 좌우로 스크롤되는 VC를 구현하기위해 XLPagerTabStrip 이라는 라이브러리를 사용하는데 이 라이브러리에서 사용하는 코드 구현 방식에서 어쩔수 없이 오류가 발생하는 부분이 있었습니다.

해결 방법은 생각보다 간단한데요. AppDelegate 에서 앱이 시작되고 XLPagerTabStrip 을 사용하는 코드가 호출되기 전에 XLPagerTabStrip 을 사용하는 VC를 한번 호출해주면됩니다.

let _ = NotificationTabVC(nibName: nil, bundle: nil)

위와 같이 한번 호출해주면 실제 사용할때 에러가 발생하지 않습니다. 이 에러는 이슈에도 올라와 있는데 Swift 의 Interface Builder 의 Generic 지원 문제로 인해 발생하는 문제 였습니다.

이런 삽질은 할때 마다 너무 힘드네요. 안그래도 Swift 빌드 느린데 빌드를 몇십번씩 하면서 테스트 하려니 중간에 다른것도 못하고 멍하니 화면만 바라보면서 이번엔 잘되라 하면서 기도하고 있으니 시간도 아깝구요.


진정한 삽질이란 이런걸까요? 작년 11월의 제가 이와 동일한 문제를 이 블로그에 iOS 삽질로 적었었네요… 글 다 작성하고 나서 아래 관련게시글로 나와서 알게됬습니다. ㅜㅜ https://code.iamseapy.com/archives/36

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

Swift 빌드가 제일 느린컴퓨터는 12코어 MacPro?

Swift 컴파일러가 느린건 잘 알려진 사실입니다. 조금이나마 개발속도를 빠르게 하기 위해 여러가지 꼼수들이 공유되고 있죠. 하지만 더 비싼 맥을 사면 다 해결될것 같지 않나요? 여기 그렇지 않다는 정보를 드리려고합니다.

링크드인에서 게시한 The best hardware to build with Swift is not what you might think 글에서는 맥프로, 아이맥, 맥미니, 맥북프로를 이용해 빌드 속도가 얼마나 차이가 나는지 확인한 결과를 공유했습니다.

결과는 충격적이게도… 맥프로가 제일 느립니다!

링크드인에서는 2015년 중반쯤 테스트를 통해 CPU 코어와 스레드 갯수가 빌드 타임에 많은 영향을 미치는것을 보고 모바일 개발자의 빠른 개발을 위해 기존의 4코어 맥북프로 대신 12코어 맥프로를 제공해 2-3배 정도의 속도 향상 효과를 얻었다고 합니다. 12코어 맥프로는 한대에 9백만원!!!(메모리와 그래픽카드 업그레이드까지 했다면 1천 2백만원!)

그러다가 최근 모바일 개발자들이 그 비싼 12코어 맥프로 대신 맥북프로를 사용하고 있는것을 보고 왜 맥프로 안쓰냐고 했더니 맥북프로가 더 빠르다고 했다네요.

2015년의 결과를 뒤로 하고 다시 테스트 해봤더니 충격적이게도 12코어 맥프로는 Swift 빌드 하는데 있어서 맥미니보다도 느린 성능을 발휘하고 있었습니다. (자세한 그래프는 링크드인 블로그를 참고하세요.)

빌드가 빠른 순서대로 나열하면 다음과 같습니다. “4코어 아이맥 27인치” > “4코어 맥북프로” > “2코어 맥미니” > “12코어 맥프로” 🙁

이런 문제가 발생한 이유는 Swift 컴파일러의 버그때문인것으로 보입니다. Compilation gets slower when allowed more concurrent jobs 요 이슈가 해결되면 맥프로도 빠르게 빌드 할 수 있겠네요 ~

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

iOS 삽질 : Unknown class xxx in Interface Builder file

아이폰 개발은 하루하루가 삽질의 연속이네요… 오늘의 삽질은 클래스 파일을 찾을수 없다고 하면서 앱이 종료(크래시)되는 현상을 고치면서 발생했습니다.

인터페이스 빌더의 ViewController에 새로 만든 VC를 지정 했고 개발 빌드까지 아무 이상이 없었습니다. 그런데 테스트 플라이트를 통해 받은 Production 빌드에서만 앱이 크래시 나길래 Xcode에 아이폰을 연결해 실행하니 앱이 종료될때 다음과 같은 메시지가 있었습니다.

daangn[19282:4846848] Unknown class _TtC6daangn15MyArticlesTabVC in Interface Builder file.
Could not cast value of type 'UIViewController' (0x1b453af60) to 'daangn.MyArticlesTabVC' (0x1072c0028).
daangn[19282:4846848] Could not cast value of type 'UIViewController' (0x1b453af60) to 'daangn.MyArticlesTabVC' (0x1072c0028).

MyArticlesTabVC는 분명히 존재하는 파일이고 UIViewController 하위 클래스가 맞습니다. 그리고 개발 빌드에서는 아무 문제가 없었죠 ~

제가 문제를 겪은 VC는 XLPagerTabStrip 라이브러리의 특정 VC를 상속받은 거였고 이와 비슷한 문제가 이슈에 등록되어 있었습니다.

Can’t connect ‘containerView’ and ‘buttonBarView’ outlets #141

상속받는 클래스가 Generic 클래스 인데 Xcode 문제로 인터페이스 빌더의 커스텀 클래스에는 Generic 클래스를 지정 할 경우 이와 같은 오류가 발생한다고 하네요. 해결은 간단하게도 AppDelegae의 didFinishLaunch 함수 제일 위쪽에 다음과 같은 코드를 추가해서 했습니다.

let _ = MyArticlesTabVC(nibName: nil, bundle: nil)

이문제는 이전에도 한번 경험해봐서 알고는 있었는데 그때는 개발 빌드에서도 앱이 종료 되었었는데 이번에는 개발빌드는 정상동작하고 Production 빌드에서만 문제가 발생해서 찾기 어려웠습니다.

참고문서

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

컴파일러 친화적으로 Swift 코딩 하기 싫다

swift

swift

swift는 생긴지 얼마 안된 언어지만 iOS, macOS 개발을 위해서는 어쩔수 없이 사용하게 되는데요. 개발을 하다보면 제일 문제되는건 swift 언어 컴파일 시간 문제입니다.

Xcode 에서 아이폰 개발을 하다보면 이전에 Obj-C 사용하던것 보다 컴파일이 느려서 시뮬레이터로 실행하면서 코드 수정하는 전체 프로세스를 느리게 만들정도죠.

그래서 swift로 개발할때는 고려해야 될게 생겼습니다. 컴파일러 친화적으로 코딩하기! ㅜㅜ 컴파일러의 컴파일 속도를 올려주는 팁들이 몇개 있는데 이걸 잘지키면 컴파일 속도가 빨라집니다.

제가 참고로한 2개의 글에 자세히 설명되어 있으니 읽어보시기를 추천드립니다.

대표적인거 몇개 소개해드리겠습니다.

rightView?.bounds.width ?? 0

위와 같이 값이 nil 이면 기본값을 제공하는 연산자는 코드 가독성도 좋아서 많이 사용하죠 ~ 그런데 이걸 아래와 같이 풀어 쓴다면 컴파일 속도가 얼마나 빨라질까요?

var width: CGFloat = 0
if let rightView = rightView {
 width = rightView.bounds.width
}

빌드 타임이 99.4% 빨라졌다네요… 5238ms 에서 32.4ms 로 빨라져요. (위의 예제는 벤치마크 코드의 일부라서 실제로 위의 코드로 하면 격차가 줄어들수도 있어요. 전체 코드는 링크 참고)

이런코드 100번 쓰면 5초 * 100 = 500초… 8분정도 느려지는거네요. 8분을 아끼기 위해서 1줄 코드를 4줄짜리로 바꾸면 100줄 짜리 코드가 400줄 될거구요.

이외에도 아래와 같은 것들이 있어요

  • 배열에 값을 추가할때 + 연산자 대신 append를 사용하면 97.9% 속도 향상!(1250.3ms -> 25.5ms)
  • 삼항 연산자를 사용하지 않으면 빌드타임 92.9% 향상!(239ms -> 16.9ms)

이런…. 다들 코드 가독성 향상이나 편리함을 이유로 코드에서 자주 사용하는것들이네요…

Swift 3에서는 그래도 이런것들이 조금 개선되었다고 합니다.

자 여러분의 선택은? 가독성을 포기하고 1줄코드를  3줄씩 늘려서 쓰고 컴파일 속도를 얻을것인가? 컴파일 속도를 포기하고 가독성이나 편리함을 추구할것인가요? 다른 옵션으로 iOS 8 지원을 포기하고 swift 3으로 넘어가는 선택도 있겠네요. 아니면 컴퓨터를 맥프로(맥북프로 아닙니다… 쓰레기통 맥 말하는거에요) 최고급 사양으로 바꾸는 선택지도 있겠네요 ㅎㅎ

저는 컴파일 속도를 포기했습니다… swift 3에 컴퓨터 사양 높이는걸 고려하겠어요

옛날 옛적에 ~ C로 코딩할때는 컴파일러 속도를 빠르게 하기위해 코딩 습관도 컴파일러 친화적으로 하고 컴파일러가 새로 나올때마다 공짜점심을 먹었다는 이야기를 들었는데… 요즘 세상에 이런 이야기를 할줄은 몰랐네요 ㅜㅜ 개발자들을 위해 Swift 컴파일러가 좀더 빠른 속도로 개선되었으면 좋겠습니다.

참고 자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

애플 푸쉬서비스(APNs) 토큰 방식 인증 추가

애플 플랫폼에서 개발하다 보면 유독 인증서를 많이 이용하는것을 볼수 있습니다. 보안 때문이라고는 하지만 구글 같은곳에서도 인증에 키를 사용하는데 애플은 인증서를 사용하는 경우가 대부분이죠. 이로 인해 대부분의 애플 개발 시작하기는 인증서 파일 만들기, 인증서 파일 등록하기,  여러대의 컴퓨터에서 인증서 사용하기 등 의 문서가 많습니다.

그런데 애플이 애플 푸쉬서비스(Apple Push Notification Service)에 토큰 기반 인증을 지원한다고 하네요!!

애플 뉴스 : Token Authentication Now Available for Push Notifications

그동안 애플 푸쉬서비스를 사용하려면 인증서를 애플 개발자 사이트에서 다운로드 받아서 openssl로 한번 파일 변환하고 이를 푸쉬 전송하는 서버에서 푸쉬 보낼때 전송했어야 했는데요. 

이제는 인증서 대신 토큰으로만 전송할 수 있게 되었습니다. 또한 인증서는 1년의 유효기간을 가지고 있어서 1년에 한번씩 갱신하는것을 까먹을경우 푸쉬가 전송되지 않는 문제도 있었는데 토큰은 유효기간이 없습니다 !!

푸쉬 인증서 타입에 토큰이 추가됨

토큰이라서 문자열이지만 파일로 받는다

만료기간이 없다


토큰을 생성해보니 p8 확장자를 가진 파일을 다운로드 하게 하는데요. 파일을 열어보면 문자열을 확인할 수 있습니다. FCM(aka GCM)처럼 단순 키 문자열은 아니라 뭔가 낚인것도 같지만… 그전에 인증서 발급할때 openssl 로 했던거 생각하면 이게 어딘가요 ㅜㅜ

푸쉬 서버를 직접 운영하고 있다면 이 새로운 기능을 위해 별도 구현을 해야되구요. 저처럼 외부 푸시 서비스를 이용하는경우에는 해당서비스에서 지원하기를 기다리면 되겠습니다 ~ (카카오 푸쉬 사용하고 있는데 해주시면 감사히 잘쓰겠습니다 ㅎㅎ)

참고로 APNs 서버 API 문서(APNs Provider API)를 보면 인증에 HTTP/2 + JWT(JSON Web Token)를 사용한다고 되있습니다. 이게 JSON으로 인증하는 표준기술이라던데 저도 어떻게 동작하는지는 모르겠는데 애플도 사용한다고 하니 괜찮은가보다라는 생각이 드네요. 

앞으로 개발자 인증서나 앱별로 별도로 만들어야 되는 프로파일도 없애주면 좋겠네요. 애플은 개발자들 불편한거 오래 방치하다가 풀어준단 말이죠… 그러면 저를 포함한 개발자들의 와우 효과는 더 커지구요 ㅎㅎ 

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^