2019의 게시물 표시

[iOS] Print Override (Print 재정의 하기)

이미지
  [iOS] Print Override (Print 재정의 하기) 안녕하세요. 이번에 Print 문의 재정의 부분에 대한 코드 공유하려고합니다. 기존의 Objective C 언어부터 진행하셨던 개발자분들은 NSLog를 .pch 파일에 재정의하여 사용하시는 분들이 많은데요.   NSLog #ifdef DEBUG #define NSLog( s, ... ) NSLog( @"<%@:(%d)> %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] ) #else #define NSLog( s, ... ) #endif 위 그림과 같이 [시간] [프로젝트명] <클래스명:(라인)> 내용 으로 출력이 가능합니다.    Print /// 2019. 12. 18 Kimjiwook /// Print문 재 정의 하여 사용함 /// - Parameters: /// - items: 출력시 사용될 내용 /// - separator: 여러 아이템일 경우 아이템 사이사이 넣을 값 /// - terminator: ... /// - file: 해당파일이름 (알아서 넣어줌) /// - line: 해당파일의 라인수 (알아서 넣어줌) /// - function: 해당파일의 호출된 함수 (알아서 넣어줌) public func printDZ(_ items: Any..., separator: String = " ", terminator: String = "\n", file: String = #file, line: Int = #line, function: String = #function) { let output = items.map { "\($0)" }.joined(separato

[iOS] 탈옥체크하기 (iOS Jailbreak Check)

  [iOS] 탈옥체크하기 (iOS Jailbreak Check) 탈옥한 폰에서 앱을 사용하는 것은 문제가 없을 수 있으나, B2B 업무에서는 정보의 보안에 대해 매우 중요하게 생각하고 있다. ipa를 빼거나 분석하여 내부에 있는 정보를 가져가는 행위를 막고자 극단적인 탈옥시 앱 팅기기를 구현해 놓았다. 탈옥구분하는 코드 공유차원으로 남겨놓는다.   Swift /// 탈옥여부 체크하기. @objc func isJailbroken() -> Bool { #if targetEnvironment(simulator) print("It's an iOS Simulator") return false #else print("It's a device") // 악의적으로 Cydia파일 경로를 수정하는 경우 SSH데몬, 쉘 인터프리터 위치 확인 및 탈옥 디바이스에서 애플리 케이션을 실행 하기 위해 필요한 Mobilesubstrate 파일 위치 체크 if FileManager.default.fileExists(atPath:"/Applications/Cydia.app") || FileManager.default.fileExists(atPath:"/Library/MobileSubstrate/MobileSubstrate.dylib") || FileManager.default.fileExists(atPath:"/bin/bash") || FileManager.default.fileExists(atPath:"/usr/sbin/sshd") || FileManager.default.fileExists(atPath:"/etc/apt") { ret

[iOS] KVC, KVO, KeyPath 알아보기

이미지
  [iOS] KVC, KVO, KeyPath 알아보기 안녕하세요. 이번에 Swift 버전의 KVC(Key Value Coding), KVO(Key Value Observing) 그리고 KeyPath 를 알아보려고 한다. 참고 Objc KVO :  https://xodhks0113.blogspot.com/2019/02/ios-kvokey-value-observing.html Objc KVC :  https://xodhks0113.blogspot.com/2019/01/ios-kvckey-value-coding.html Sample App :  http://github.com/kimjiwook/KVCDemo Swift 4.x 이상부터 KeyPath 접근하는 방식이 변경되었는데, 과거 버전에서 Property를 String 값으로 쓰다보니 오타 발생시 앱이 죽는현상때문에 꺼려지는 방식이였다면, 이번에는 Property 참조하는 방식으로 제공이 되어 생각보다 편하게 사용할 수 있는 것 같다.    KVO 객체 만들기 Objc 접근 가능해야하며, NSObject 상속받아야한다. + dynamic 키워드를 사용해야 KVO 를 사용할 수 있다. // Swift KVC, KVO, KeyPath 테스트 하기 @objcMembers class KVCObject: NSObject { // KVO 시 NSObject 상속 필요함. (KVC 에는 상관없음) dynamic var name = "" // dynamic 을 사용해야 실시간 변화 감지가 가능함. dynamic var age = 0 }   KVO, KVC NSKeyValueObservation 변수를 선언하여, 클로져 타입으로 선언하여 사용한다. keyPath \.name 형식으로 KVC 사용이 가능하다. class ViewController: UIViewController { let kvcObject1 = KVCObject(

SwiftPM Catalog 둘러보기

이미지
  SwiftPM Catalog 둘러보기 Swift 관련 개발하다보면 Open Source 를 찾아보게 되는데, 해당 Open Source를 정리해서 보여준 앱이다. 가끔씩 보면서 어떤 트렌드와 방식을 선호하는지 볼때 유용할 것 같아서 정리한다. 링크 :  https://zeezide.com/en/products/swiftpmcatalog/ 사이트는 아래 이미지와 같고, 다운로드 받아서 앱으로 쓰는 형식이다. 앱 내부에서는 카테고리별 인기있는 Open Source들이 정리가 되어 있다.   마무리 필자의 경우 위에서 간단하게 설명했듯이 내가 쓰고 있는 Open Source도 보고 혹은 비슷한 인기있는 항목을 볼때 사용하려고 한다. 이 앱을 높게 평가하는게 벌써 Swift UI 관련된 Open Source들도 업데이트 되어 정리된 모습을 보여주고 있다.

[iOS] UIPasteboard (iOS 클립보드 복사하기)

  [iOS] UIPasteboard (iOS 클립보드 복사하기) iOS 클립보드에 복사하는 함수에 대해 간략 알아보기 iOS 3.0 이상 사용가능 (자세한 내용 링크 참조) https://developer.apple.com/documentation/uikit/uipasteboard   Swift UIPasteboard.general.string = "클립보드에 복사할 내용"   Objective C [[UIPasteboard generalPasteboard] setString:@"클립보드에 복사할 내용"];

[iOS] Multiple commands produce ... Error 처리

이미지
  Multiple commands produce ... Error 처리 Git Merge 하다가 Project file에 깨졌을때 생겼던 에러인데 처리방법에 대해 간단하게 설명하고자 한다.   [참고] 필자의 Error Multiple commands produce '/Users/jiwook/Library/Developer/Xcode/DerivedData/Bizbox-A-dmpaovlownpwxobpibtaujqsmtjm/Build/Intermediates.noindex/Bizbox-A.build/Debug-iphonesimulator/Bizbox-A.build/FormExtractPageViewController-PartialInfo.plist': 1) Target 'Bizbox-A' (project 'Bizbox-A') has compile command with input '/Users/jiwook/Documents/Source/Douzone_Git/BizboxA/Bizbox-A/Bizbox-A/FormExtractPageViewController.xib' 2) Target 'Bizbox-A' (project 'Bizbox-A') has compile command with input '/Users/jiwook/Documents/Source/Douzone_Git/BizboxA/Bizbox-A/FormExtractPageViewController.xib' 다행히 생각보단 심플한데, Project > Targets > Build Phases > Copy Bundle Resources 에 해당 파일이 중복되어 있는게 존재한다. 이부분 - 로 제거해주면 끝난다. 끝.

가정용 히터 구매기 (디토브 프리미엄 컨벡터 히터)

이미지
  가정용 히터 구매기 (디토브 프리미엄 컨벡터 히터) 겨울이 점점 다가오고, 아기 씻길때와 자기전에 방에 온도를 올리기위한 용도로 구매한 히터 디토브 프리미엄 컨벡터 히터 (DGO-EC1500) 현재는 3주정도 되어가고 만족하고 있습니다!  (다만 위치를 옮길때 불편함은 있내요) 아래 20분간 방온도 변화 동영상 있습니다. 와트가 1500W 와 1200W 인가 두가지 모델 있었는데, 높은걸로 구매하였습니다. 간단한 구성품 본체, 스탠딩 거치대, 본체 손잡이, 본체 벽걸이 브라켓, 설명서 로 구성되어있습니다. 설명서 (패스~) 전면 디자인 (이것때문에 샀습니다.) 후면부는 가운데 손잡이 달수있고, 양옆으로 벽걸이형 브라켓이 있습니다. 저는 손잡이만 달았습니다. (전체 착용은 아래로) 옆면 디자인 실제로 사용했을때 1단과 2단, 바람의 양이 있는데, 바람의 양은 건들지 않고, 켜놓은 자리에 사람이 있을때는 1단, 없는곳에 공간을 데울때는 2단 이렇게 사용하고 있습니다. (딱 맞는듯) (조립조립....) 스탠딩 완성 후면부 손잡이(플라스틱인데, 사용 후 뜨겁진 않는데, 뒷면은 뜨거워서 조심해야합니다.) 20분간 방온도 변화 동영상 방문 닫고 20분간 돌렸는데, 공기청정기 수치가 좋진 않내요. 사용하는데는 문제가 없고, 매우 만족하고 있습니다. 다만 전기세가 얼마나오는지 확인은 해봐야겠내요. 이만 끝. #디토브, #가정용히터, #디토브 히터, #디토브 컨벡터 히터, #디토브 프리미엄 컨벡터 히터

[Xcode 오류] ERROR ITMS-90534: "Invalid Toolchain. Your app was built with an unsupported version of Xcode or SDK

이미지
아주 신박한 에러가 발생하여, 공유차원으로 포스팅합니다. ERROR ITMS-90534: "Invalid Toolchain. Your app was built with an unsupported version of Xcode or SDK. If you plan to submit this build to the App Store, make sure you are using the GM version of Xcode 10.1 and the SDK for iOS 12.1 and watchOS 5.1, Xcode 7.1 and the SDK for tvOS 9, or Xcode 6 and the SDK for macOS 10.9 or later. If you are using an Xcode beta version to test your app, make sure you are using the latest supported version. For more information about supported beta versions, view the App Store Connect What's New page (https://developer.apple.com/app-store-connect/whats-new/)." WARNING ITMS-90703: "Deprecated Xcode Build. Due to resolved app archives issues, we have deprecated Xcode 11.2 on November 5, 2019. Download Xcode 11.2.1 or newer, rebuild your app and resubmit." 분명 2019. 11. 06(수) 에 배포가 되었는데, 2019. 11. 07(목) 부터 이와 같은 Error 가 발생하였다. 내용을 확인해보면 Xcode 11.2.1 버전에서 배포하라는 것이다. 하지만 Xcode 11.2.1 버전은 배포 되지

블로그/웹 소스코드 정리하기 (Code Prettify 사용하기)

이미지
  블로그/웹 소스코드 정리하기 (Code Prettify 사용하기) 안녕하세요. 오늘은  기존에 사용중이던, ColorScripter (정리된글 : https://xodhks0113.blogspot.com/2018/08/additing-blog-sourcecode.html ) 갑자기 접속이 되지 않고 있어서 블로그를 쓰다가 난처해 졌습니다. (2019년 10월 30일 블로그 글쓰다보니깐 사이트가 다시 접속되내요 ^^) 그래서 추가적으로 다른방법으로 소스코드 정리하는 방법에 대해 알아보았습니다. Code Prettify ( git :  https://github.com/google/code-prettify  ) 해당 방식은 블로그 글의 HTML 부분의 script를 삽입하여 <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> class 의 prettyprint 를 찾아 CSS를 입혀주는 방식입니다. <pre class="prettyprint">class Voila { public: // Voila static const string VOILA = "Voila"; // will not interfere with embedded tags . } </pre>   테마와 지원언어 필자의 경우 블랙테마를 선호하며, Swift 언어를 지원하는걸로 Script 선어하여 미리 사용해 보았다. (두가지 테마를 한 HTML 에서 쓸 수 없어 사진과 링크로 공유합니다.) 블랙테마, Swift 적용된 링크 Git 주소의 들어가면 자세한 설명이 있으나 필자가 적용한 정보도 공유드립니다. 필자의 경우 lang =swift, skin =desert 적용하였습니다. &l

iPhone to iPhone 기기옮기기

이미지
  iPhone to iPhone 기기옮기기 iPhone 개발일을 하면서 아이폰을 지원 받는데, 개인용으로 쓸때도 있고 개발용으로만 쓸때도 있다. 개인적으로는 백업을 iCloud 통해서 받을수도 있지만 iPhone to iPhone 으로 옮기는 방법도 매우좋은것 같아서 포스팅 한다. 1. 인근에 새 iPhone이 있으면 설정할 것 인지 물어봄. 2. 원형 홀로그램같은 이미지가 새 iPhone에 뜨고, 기존에 쓰던 iPhone으로 인증함. 3. 기다리기... (생각보다 오래걸림. 12:30분 시작함) 4. 여기서 선택을 할 수 있습니다. iPhone to iPhone (오래걸린다는 가이드) iCloud 다운로드 (덜걸린다는 가이드) 필자는 기본적인 정보는 이미 옮겨졌고, 앱다운로드는 iCloud 통해서 받기로 선택함. 5. 여기서 부터는 기존 iPhone 필요없음. 6. 많은 기다림의 시간.. 7. 복원 완료까지 1시간 30분 걸렸다. #. 필자는 글을쓰고 있는 와중에도 아직도 앱들이 전체 설치 되지 않았다. (4:40분) 보통 6시간 정도면 거의다 되는것 같다. 끝.

iPhone 11 Pro 미드나잇그린

이미지
매년 iPhone 새폰을 회사에서 받는데, 이번에는 미드나잇그린색이 이쁜것 같아서 받았다. 이제는 뭐 매년 받으니 개봉기는 할 것 없고, 그냥 이쁜것 같다. 새기기 옮기기 :  iPhone to iPhone 기기옮기기 + 여기서 가장 이번에 좋게 느껴지는 18w 고속충전기 ㅎㅎ 쫌 써봐야겠지만 카메라 성능이 확실히 좋아진것 같다. 끝.

iOS13 _placeholderLabel.textColor 접근오류

  iOS13 _placeholderLabel.textColor 접근오류 기존의 UITextField 의 Placeholder Color 를 변경하려고 KVC 방식을 활용하여 사용하고 있었는데, Xcode 11, iOS 13 빌드시 앱이 죽는 현상을 발견하였습니다. (이번에 유독 이런 부분이 많아서 참 애플이 미워지고 있습니다.....)   기존 코드 [self.textFieldPassword setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"]; Extention을 활용하여 UITextField Placeholder Color를 변경하는 방법을 구현하였습니다.   변경 코드 [self.textFieldPassword setCommonPlaceholderColor:[UIColor lightGrayColor]];   내부 코드 import UIKit extension UITextField { /// UITextField Placeholder setColor (내부의 키값을 Class화 시켜서 작업함) /// - Parameter color: UIColor 값 @objc(setCommonPlaceholderColor:) // 함수인자가 존재시 objc 에서 인식못할때 이렇게 표현가능함. func setCommonPlaceholderColor(color:UIColor) { let ivar = class_getInstanceVariable(UITextField.self, "_placeholderLabel")! let placeholderLabel:UILabel = object_getIvar(self, ivar) as! UILabel placeholderLabel.textColor = color } } 이번에 느낌

iOS13 APNS deviceToken 관련

  iOS13 APNS deviceToken 관련 안녕하세요. 이번에 iOS13 부터 deviceToken 가져올 때 이슈사항에 대해 공유드립니다.   이슈사항 iOS12 환경  deviceToken 데이터 형식 < fa26d6a1 711c10f2 fe15aa98 8beb4a5e 385bc0a4 d6e8b839 07b4f501 648722eb > cs iOS13 환경  deviceToken 데이터 형식 {length  =   32 , bytes  =   0xfa26d6a1  711c10f2 fe15aa98 8beb4a5e ... 07b4f501 648722eb } cs   대응 iOS 12 환경 대응을 위해 두가지 동시에 사용하였습니다. 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 // 디바이스 토큰 획득 -  ( void )application:(UIApplication  * )app didRegisterForRemoteNotificationsWithDeviceToken:(NSData  * )deviceToken {      // iOS 13에서 deviceToken 값이 변경되어 처리 로직 수정함.     NSString  * tokenStr  =  @ "" ;      if  (@available(iOS  13. 0 ,  * )) {         NSUInteger length  =  deviceToken.length;          if  (length  ! =   0 ) {              const   unsigned   char   * buffer  =  deviceToken.bytes;       

iOS13 WKWebKit decidePolicyForNavigationAction: (iPad UserAgent Desktop 문제)

이미지
  iOS13 WKWebKit decidePolicyForNavigationAction: (iPad UserAgent Desktop 문제) 이번 iOS13 때 예상치 못했던 점인데, 유지보수건에서 확인하다보니 Objective C 언어로 설명하겠습니다. iOS Client만 개발을 하다보니 WebKit 관련해서 하이브리드 작업을 하든, 디스플레이만 하든 티가 안나서 문제 될 것은 없었습니다. "iPad에서 Useragent 값이 Desktop" 으로 표현되어, 기존에 Web부분에서 Mobile 과 Desktop 구분하여 사용 하던 WebPage 인 경우 작동이 다르게 되는 오류가 발견되었다. WKWebpagePreferences 추가로 현 디바이스를 Mobile, Desktop 으로 설정할 수 있어졌다. 그런데...  iOS 13 전용 decidePolicyForNavigationAction: Delegate 에서 추가해야한다는 점   이번에 신규 추가된 Navigation Delegate 참고 Apple :   webView:decidePolicyForNavigationAction:decisionHandler: 해당함수는 iOS13에서만 작동하고 해당함수가 작동하면, 기존에 있는 decidePolicyForNavigation 은 작동하지 않는다고 설명해져있다. 필자의 경우 로직 코드를 하나로 합치기 위해 아래와 같이 코드를 구현하였다.   샘플 코드 // 기존 iOS 13 미만 WKWebView Navigation Delegate -  ( void )webView:(WKWebView  * )webView decidePolicyForNavigationAction:(WKNavigationAction  * )navigationAction decisionHandler:( void  (^)(WKNavigationActionPolicy))decisionHandler {     

[iOS] iPad Multi Window Example (간략소개)

이미지
  iPad Multi Window Example (간략소개) iPad OS 올라가고 나서 부터 메모앱이 여러창이 띄워지기 시작하면서 어떻게 구성하는지 궁금해서 알아보기 시작하였다. 샘플 예제 구동 동영상 Xcode 11 이상 버전에서 Project > Target 의 Supports multiple windows 체크박스가 추가되었다. 설정 해준다. (여기까지만 해주어도 multiple windows 는 지원이 끝이다. 추가 Code 필요없음) 매우 심플.. 필자의 경우는 DragDelegate 를 UIView에 추가하여, UIView를 Drag시에도 multiple windows 를 지원하도록 예제를 만들어 놨습니다.   예제소스 Example(Git) :  https://github.com/kimjiwook/iPadMultiWindowExample

[iOS] UIView Shadow 효과

이미지
  UIView Shadow 효과 간략 샘플 코드 tempView.layer.shadowOpacity  =   0. 7 tempView.layer.shadowOffset  =  CGSize(width:  - 20 , height:  0 ) tempView.layer.shadowRadius  =   10 tempView.layer.masksToBounds  =   false cs shadowOffset 으로 그림자 효과의 위치값을 수정할 수 있다.

[Swift 공부] 접근제어

[Swift 공부] 접근제어 접근제어는 코드끼리 상호작용을 할 때 파일 간 또는 모듈간 접근을 제한할수 있는 기능이다. 불필요한 접근으로 코드가 의도치않은 결과값을 만들 수 있기에 접근이 가능 부터 불가능하게 만들수 있는 키워드이다. 5가지 정도 있다는 형식으로 알면 좋을것 같고, 실제로 사용할때는 public 과 private 를 가장 많이 사용한다. 접근수준 키워드 범위 비고 개방 접근수준 open 모듈 외부까지 Class 만 사용 공개 접근수준 public 모듈 외부까지 내부 접근수준 internal 모듈 내부 파일외부비공개 접근수준 fileprivate 파일 내부 비공개 접근수준 private 기능 정의 내부   공개 접근수준 public 자신이 구현된 소스, 파일, 모듈 등 접근이 가능하다.   개방접근 수준 open 클래스와 클래스의 맴버에서만 사용 가능.   내부 접근수준 internal 기본적으로 모든 요소에 암묵적으로 지정하는 기본 접근수준   파일외부비공개 접근수정 fileprivate 구현된 소스파일 내부에서만 사용할 수 있는 접근수준   비공개 접근수준 private 접근수준이 가장 한정적인 범위지정된 요소는 그 기능을 정의하고 구현한 범위내에서만 사용가능

[Swift 공부] Guard 알아보기.

  Guard 알아보기 Swift에서 {if let 변수명} 은 Objective C 에서는 느껴보지 못한 확인 절차가 너무 좋았던 점 중에 하나이다. 이런 확인절차에 사용할 수 있는 Guard 를 알아보려고한다.   if let 해당 코드가 맞다면, if {내부에 정상적인 코드 작성}   guard 해당코드가 아닌 경우 else{예외처리} 밖에서 변수 사용가능 guard 처리로 예외체크할 시에 라인이 깔끔하다는 점과 변수를 밖에서도 사용할 수 있다는 장점이 있다. 좀더 많은 예외처리항목과 그 변수값으로 다른 예외처리 체크까지 할 때 편리하게 사용할 수 있다. import  UIKit //1. Guard 를 if let 과 비교하기 // if let 옵셔널 활용시 func  ifMyName(name: String ?)  - >   String  {      if   "soo"   = =  name {          return   "당신의 이름은 [X] 입니다."     }               else   if   let  resultName  =  name {          return   "당신의 이름은 \(resultName)입니다."     }           else  {          return   "당신의 이름은 [X] 입니다."     } } // guard 옵셔널 활용시 func  guardMyName(name: String ?)  - >   String  {     guard  let  resultName  =  name, name  ! =   "soo"   else  {          return   "당신의 이름은 [X] 입니다."     }           return   &