캐시 할 때는 당연히 NSCache를 썼는데 왜 쓰는지에 대해 깊게 생각하지 않았었다.

이전에 했던 프로젝트 중에 NSDictionary로 캐시 구현한게 있길래 구체적으로 차이점을 짚어 보려고 한다.


결론부터 말하면 딕셔너리보다는 NSCache 가 더 유용하다.


1. NSCache는 메모리 관리가 기본적으로 제공된다.

다른 앱에서 메모리를 더 사용하려고 하면 캐시되어 있던 데이터를 지우고 메모리를 해제한다.


2. NSCache는 Thread-safe 하다.

캐시 데이터를 읽고 쓰고 지울때마다 따로 lock을 해줄 필요가 없다.

반면 NSDictionary는 Threadd-safe 하지 않기 때문에 데이터 접근할 때 따로 처리해줘야 한다.


3. NSDictionary는 Key 값을 copy하지만 NSCache는 retain 카운트만 증가 시킨다.

복사를 지원하지 않는 객체까지 포용한다.



[ 관련 클래스 ]


NSDiscardableContent

객체를 더이상 사용하지 않을 때 바로 메모리 해제할 수 있는 메소드가 정의되어 있는 프로토콜


NSPurgeableData

NSMutableData를 상속받으며 NSDiscardableContent 프로토콜이 구현되어 있음



* 참고문서 : https://developer.apple.com/documentation/foundation/nscache


크롬만 쓰다보니 사파리에 무지하다.

플젝 웹뷰 디버깅 얘기하다가 사파리도 가능하다는 정보를 입수.


사파리 설정에서 마지막 탭에 개발자 도구 체크박스로 켜고

휴대폰 사파리 설정에서 웹속성 켜면

웹뷰디버깅 가능!!


그러나 나는 크롬빠라 쓰진 않을 듯;;


***사파리 설정 외에 프로젝트에도 설정 추가해야 사용할 수 있음.

[preferences setValue:@YES forKey:@"developerExtrasEnabled"];



p.s 이건 ㅈㄴㄱㄷ 얘기 나온 웹 디버깅 툴

https://www.telerik.com/fiddler

iOS9 부터 AddressBook framework 가 deprecated 돼서 CNContact framework 를 사용하게 됐다.

그런데 시작부터 문제가 스물 스물 발생. 그 중 대표 이슈만 정리해 본다.


#1 NavigationBar is hidden on CNContactViewController for Unknown and it never shows up again.


이 문제는 전세계 ios 앱 개발자에게 깊은 빡침을 선사했다.


[CNContactViewController viewControllerForUnknownContact:] 로 호출된 vc에서 연락처 공유 / 기존의 연락처에 추가 등의 메뉴를 선택하면 새 화면이 present 로 뜨면서 앱의 네비게이션바가 hidden 된다. 그리고 이 화면을 dismiss하면 기존의 네비게이션바가 나타나야 하는데 보이지 않는다.

AddressBook에선 잘 됐는데.. 에헤이 이 사람들 일을 하다 말았넹..


이전 화면으로 돌아가기 위해선 앱을 재 실행하는 수밖에 없다. ㅠㅁㅠ


작년 WWDC 에서 (따지는 표정으로)물어볼 겸 찾아갔는데 contact 프레임웍 유닛을 만날 수 있는 시각을 오해해서 이미 집에 가고 없었다. 안돼 ㅠㅡㅠ 

그래도 다른 파트 사람한테 설명해주고 프레임웍에 무슨 문제가 있는지 같이 확인 후 연락기다리겠다고 하고 헤어졌는데 iOS10이 릴리즈됐을 때도 변화 없길래 걍 포기.


올해에 커스터마이징 해야지 하고 있었는데 오옷!!

어제 확인해보니 언제 수정됐는지도 모르게 정상동작한다. 단, iOS 10 이상에서만.

애증의 애플... 이런 기본적인 기능은 잘 구현해줬으면 좋겠다.



// NOTICE:  I realized navigationbar hidden issue has fixed for iOS10 only.



#2 CNContactViewController를 push 했을 때 발생하는 UI 문제.


View의 좌측 끝 부분 터치가 안된다. 하지만 모달로 구현하면 잘 동작해서 의아함. 



#3 Left button is disappeared after selecting menu on Unknown ViewController


문제가 발생하는 동선은 다음과 같다.

1. 좌측에 닫기 버튼 나오도록 세팅하고 모달로 띄움.

2. 새 연락처로 등록으로 들어가 완료 버튼 누르면 화면이 닫히면서 네비게이션바가 나타남. 

3. 우측에 파란색 편집 버튼이 생기는데 좌측에 넣었던 close 버튼이 사라짐.

=> 10.2 이상에서는 닫기 버튼이 살아있으나 오른쪽 편집 버튼 파란색인 현상은 그대로임.


뭔가 동작이 이상한데 unknown 뷰의 메뉴를 선택하고 닫을 때 이벤트를 받을 수가 없다.

편집 버튼이 나타나면서 이상해지길래 allowsEditing = NO 로 세팅했더니 편집 기능을 사용할 수 없지만 네비 바의 버튼들이 이상해지는 문제는 막을 수 있다.

이 완벽하지 않은 해결에 찝찝해하며 일단 이 이슈는 여기까지 정리하는 걸로!!

이슈 : UIAlertController 로 변경되어 alertview를 present 하면서 keyboard 를 닫는다.


presenting을 할 때 키보드를 닫는게 디폴트인듯하다.

이전 정책으론 AlertView 는 다른 뷰에 영향을 주면 안되는 거였는데 어느 순간 오래된 클래스들을 변경하면서 정책들이 바껴서 고생하는게 한두번이 아니다.

커스텀 뷰를 띄우든 모달에 익숙해지든 해야겠다. 다른 앱들은 커스텀으로 많이 옮겨간듯.

커스텀 키보드를 설정한 후 마이 앱에서 커스텀 키보드를 한번 열었다가 메뉴를 전환해서 커스텀 인풋뷰로 스위칭하면 커스텀 키보드가 인풋뷰 위를 덮는다

인풋뷰가 UIView 면 발생하지 않으나 UIViewController 인 경우 시그널을 받는건지 키보드가 자연스레 올라온다


이런 젠장

하루하루 풀어나가야 할 버그는 늘어만 가는데 해결되는 건 없구나...


AppDelegate api 중에

   - (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier 

가 있는데 키보드를 열때마다 호출된다. 


여기서 extensionPointIdentifier 가 UIApplicationKeyboardExtensionPointIdentifier인 경우 NO를 리턴하면 커스텀 키보드가 실행되지 않는다.


버뜨!!

내가 원하는 건 특정 상황에서만 사용하지 않는 것이므로 조건을 주어 처리. 해결해보리라.







What : 

앱스토어에 섭밋하는 과정에서 앱아이콘 관련 에러가 발생한다. 

이름이 이상하다는 내용이 떠서 처음엔 이름을 계속 변경해봤으나 같은 에러만 연달아 발생했다. 

구글링하다가 드디어 원인 발견!!


Why : 

Watch OS 1을 사용했을 때 추가된 App Icon assets 이기 때문에 Watch OS 2 에서는 불필요한 이미지가 존재한다. 

그것이 바로 App Icon 44 X 44 사이즈이다. (Long Look size)


이 이미지를 지우고 빌드해서 다시 섭밋하면 에러는 사라진다. 

하지만 우린 아직 WatchOS1 과 WatchOS2를 모두 지원하기 때문에 언제까지 유지해야 하나 고민 중이다. 

WatchOS1 을 사용하는 유저가 소수지만 존재하기 때문에 지우는 김에 앱 아이콘 옵션도 변경해야겠다.


해당 파일을 그냥 지우면 App Icon Asset 세팅이 예전 그대로이기 때문에 파일이 없다고 경고한다.

그래서 다음 과정에 따라 옵션을 변경하면 asset 환경을 OS2 용으로 설정해서 44x44 이미지는 unassigned 로 바뀐다.


Watchkit app bundle > Assets.xcassets > Select AppIcon.appiconset in Xcode7

Xcode 우측에 utilities section 에서 3번째 버튼을 선택하면 App Icon 설정에 Apple Watch 항목에 'watchOS All Versions' 와 'watchOS 1.0 Specific' 이 존재한다.





해당 화면에서 'watchOS 1.0 Specific' 을 Uncheck 하면 된다.




RecordID 는 int 타입인데 새로 생긴 contact framework 에서는 identifier 타입이 NSString이다.

이럴수가...

이왕이면 관련 api가 오픈되어 있길 바랬으나 과거의 코드를 가져오는 걸 싫어하는지 recordID 로 contact를 fetch 할 수 있는 api는 private 으로 선언되어 있다.


기존의 함수형에서 objective-c / swift 에 걸맞게 객체형으로 변환한 것까진 좋은데 어째 영... 불안정한 느낌이다.


나름 고민하다가 조언을 받아 두 ID 사이에 연결고리가 없으니 마이그레이션으로 contact를 새로 쭉 끌어오기로 결정했다.


참고 URL : https://forums.developer.apple.com/thread/7063

Reference URL : https://forums.developer.apple.com/thread/17888


왜 이렇게 느린거야

UIImage 의 imageNamed: 메소드 퍼포먼스가 약 20배 가량 느림

야 사과머리들아 -

이런거 릴리즈해서 식겁하게 하지 좀 말어~~

와치앱 수요도 적고 마음에 드는 성능을 가진 앱이 아니라서 추후 ios 8 따위(ㅋㅋ) 버릴지도 모르겠지만,

일단 유지시키고 watchOS 2 를 지원하는 번들을 하나 더 만들기로 한다.


뭔가 망가뜨릴지도 모른다는 불길한 예감도 들고~ 유지하고 잘못되면 롤백하면 되니까 ㅋ


document엔 걍 번들 하나 더 추가해서 복사를 하든 새로 만들든 원하는대로 하면 돼~!! 라고 간.단.히. 쓰여있길래 아 겁나 간단하구나 하고 번들 추가했다가 지원스킴이 많은 것을 깜빡하고 빌드 오류 수십번 만났다;;;;

매번 할때마다 적응이 안되는 빌드 세팅 ㅋ


XCode 7 에서 와치 번들을 새로 만들어야 watchOS 2를 지원하는 환경으로 세팅된다.


the operation couldn’t be completed. (launchserviceserror error 0.)


시뮬레이터로 일단 빌드해보려고 시도했으나 역시 나답게 에러 띠링 ~

구글신께서 말씀하시길 Bundle ID 문제라길래 이럴줄 알았다 하며 이리 뒤적 저리 뒤적


와치 앱이 네이티브화 되어서 익스텐션이 와치 앱에 소속되어 번들 아이디 주소도 바뀐다.


예전엔 >

com.app.name.watchkitapp

com.app.name.watchextension


현재는 >

com.app.name.watchkitapp

com.app.name.watchkitapp.watchextention


자, 얼추 다 맞춘거 같아!!


런 클릭!!!!


..."또 에러다 한방에 좀 잘해라 code = 0"


Watch Extension 에 세팅할게 하나 생겼다

Info.plist > NSExtension > NSExtensionAttributes > WKAppBundleIdentifier

여기에 watch app 번들 아이디를 넣어주면 된다


자잘하게 세팅 할 게 좀 있네...

후하 드디어 런이 실행된다!!!!!


별것도 아닌데 삽질 했네 나의 인생이여 ㅋㅋ


일단 시뮬에서만 돌아가는 상황이므로 디바이스 빌드에서도 잘 돌아갈런지는 ㅋ

참조 URL

http://www.raywenderlich.com/108415/watchkit-for-watchos-2

http://www.kristinathai.com/



1. openParentApplication 메소드가 사라지고 watch connectivity framework  데이터 통신

 sendMessage : 바로 전송

 transferData : 백그라운드에서 전송 가능, 앱이 런칭되면 데이터 받아옴

 WCSessionDelegate data 수신


2. NSURLSession  통해 data 다운로드 가능, Application Transfer Security(ATS) 이슈로 http  시작하는 링크는 제대로 동작하지 않음 ATS 옵션은 기본이므로 disable 하고 싶은 경우 해당 url  대해 설정을 해줘야 


Watch Connectivity framework는 iOS9 이상에서 사용 가능하다.


3. 애니메이션 가능한 항목

 alpha

 width and height

 vertical and horizontal alignment

○ background color

○ layout group insets

○ 글랜스와 노티는 지원하지 않음

○ 애니메이션 timing curve나 끝나는 시점을 캐치 수는 없음


4. 접근 가능한 하드웨어

○ Heart rate sensor : HealthKit

https://developer.apple.com/library/prerelease/watchos/documentation/HealthKit/Reference/HKWorkout_Class/index.html#//apple_ref/doc/uid/TP40014744-CH1-SW13

○ DigitalCrown : Picker

○ Taptic Engine : WKInterfaceDevice -> playHaptic: with WKHapticType

○ Accelerometer : CMMotionManager

○ microphone : Recording 기능, WKInterfaceController presentAudioRecordingControllerWithOutputURL:preset:maximumDuration:actionTitle:completion:  사용


5. New Interface Objects

○ WKInterfacePicker : 디지털크라운으로 스크롤해서 동작

  - text, images 또는 둘의 조합으로 가능

  - List, Stacked, Image Sequence 3가지 타입

○ Alert : presentAlertControllerWithTitle(_:message:preferredStyle:actions:), WKAlertAction


6. Custom Complications

https://developer.apple.com/library/prerelease/watchos/documentation/General/Conceptual/AppleWatch2TransitionGuide/DesigningaComplication.html#//apple_ref/doc/uid/TP40015234-CH11-SW1

+ Recent posts