본문 바로가기

분류 전체보기

(351)
애플에서 무손실 음원을 즐기는 방법 우리는 스트리밍의 세상에 살고 있다. 우리가 아는 많은 것들이 디지털화돼 인터넷을 떠돌아다니고, 우리는 언제는 접속해 이를 즐길 수 있다. 결론적으로 불과 몇 년 사이에 '굉장히 큰 용량'은 그 수요가 줄게 됐고, 음악이나 영화, 사진을 핸드폰 등의 휴대기기에 넣는 그 번거로움도 기억의 저편으로 사라져 가는 요즘이다. 모두가 각자가 원하는 모든 것을 그렇게 즐길 수 있으면 좋았을 것이다. 하지만 얽히고설킨 이해관계와 산업과 서비스는 태생이 모두를 만족시킬 수 없다. 이건 현실이다. 음악도 그렇다. 좋아하는 노래가 모종의 이유로 더 이상 스트리밍이 불가하거나, 원하는 앨범만 서비스에서 쏙 빠진다거나, 수록곡 중에 원하는 음원만 쏙 빠지는 일이 있기 마련이다. 산업이 커지고 안정화된 지금은 보기 힘든 경우지..
[~2022.04.30] 명동, 대부도, 일상 (Ricoh GR 3x, iPhone 13 mini) 서론 RICOH GR 3x / 포지티브 필름 대부분 보정 없음(못함) 조금 더 바빠진 4월 본론 4월 9일 애플스토어 명동 애플 스토어 오픈 행사에 다녀왔는데, 애플 스토어야 뻔하니 그렇다 치고, 양 옆의 이재효 작가의 작품과 빠키의 작품들에 더 관심이 많았던... 입장 시간 전에 보안 직원에게 '이거 보러 왔는데 봐도 돼요?'라고 물었더니 조금 당황하는 기색은 있더라. 나사 하나 빠진 사람이라 죄송합니다. 😂 그런 사람이 나만 있는 건 아닌지, 외국인 사진사를 한 명 만났다. 너무 멋진 분이라 지금은 내 배경화면으로도 쓰는 사진. 책 읽으러 청계천에 가다가 찍은 할리... 횡단보도 앞에 세워져 있길래 신호 바뀌기 직전에 후다닥 찍어 봤다. 근데 여기 대시면 안 돼요~ 4월 16일 집 옥상 커스텀 설정으..
205~ 206. JSON JSON JSON은 Java Script Object Notation의 줄임 말로, XML을 대체하는 개방형 데이터 표준 포맷이다. { "Key" : Value } 위와 같은 Dictionary와 유사한 구조로, 전체가 일반 txt로 되어있어 가독성이 높고 parsing이 편한 것이 장점이다. 기본적인 문법은 동일하며 다음과 같다. '{'로 시작해서 '}'로 끝난다. Key는 항상 문자열이다. Value로 지정할 때 문자열은 " "로 감싸 표시하고, 수와 null은 별도의 처리 없이 직접 표시한다. '[ ]'로 감싸면 배열을 의미한다. Encodeing과 Decoding Json 파일을 받으면 이를 swift가 다룰 수 있도록 encoding과 decoding을 진행해야 한다. 인스턴스의 데이터를 JSO..
204. App Transport Security (ATS) App Transport Security (ATS) ATS는 iOS9에서 도입된 보안 요소다. TLS, AES, SHA-2의 보안 프로토콜을 활용하는 HTTP 프로토콜의 개선 프로토콜인 HTTPS가 2000년 RFC 2818 표준으로 등재되면서 2015년 업데이트된 iOS9 이상에서는 HTTPS 프로토콜을 사용하도록 적극적으로 유도했고, 최신 버전에서는 특별한 경우가 아니라면 HTTPS만 사용하도록 권장하고 있다. HTTP는 모든 데이터가 일반 text의 형태로 전달되며, HTTPS는 TLS 프로토콜을 활용해 암호화된 형태로 전달하는 것이 특징이다. 현재는 거의 대부분의 환경이 HTTPS를 사용하도록 만들어져 있지만, 만약 충족할 수 없다면 앱의 ATS 설정을 변경해 HTTP 프로토콜을 사용하도록 허용할..
203. Display Web Contents Display Web Contents WebKitView는 Scene에 delegate로 연결한다. WebContentViewController.swift > viewDidLoad() override func viewDidLoad() { super.viewDidLoad() navigationItem.largeTitleDisplayMode = .never webView.navigationDelegate = self urlField.text = "https://www.apple.com" } Scene에 진입하면 애플 홈페이지의 주소로 urlField를 채운다. WebContentViewController.swift > UITextFieldDelegate extension WebContentViewContro..
202. Networking Networking 일반적인 작업들이 기기 내부에서만 이뤄지는 것과는 달리. 네트워킹은 데이터가 외부로 전송되고, 외부에서 전송받기도 하기 때문에 여러 외부적 요인을 고려해야 한다. 특히 한 곳에 고정되어 사용되지 않는 모바일은 더더욱 중요하다. Gideline 가능한 한 High-Level Api를 사용할 것 필요한 데이터만 전송할 것 Cache를 적극적으로 활용할 것 비동기 방식으로 구현할 것. 만약 동기 방식으로 구현해야 한다면 mainThread를 점유하지 않도록 할 것 Hostname을 사용할 것 HTTPS를 사용할 것. IPV4를 사용하지 않도록 하고, 특정 HW를 위해 사용해야 한다면 관련된 정보를 함께 제출할 것 API URLSession 일반적인 네트워크 기능 URLSession은 기존의..
201. Migration Migration CoreData는 Stack을 초기화할 때마다 데이터 모델을 검증한다. Light Weight Migration (Automatic Migration) LWM은 Core Data의 기본 기능이며, 아래의 방식으로 동작한다. 실제 저장소에 저장된 파일과 데이터 모델이 동일하면 Stack을 초기화한다. 실제 저장소에 저장된 파일과 데이터 모델이 동일하지 않다면 차이점을 분석한 후 mapping 모델을 생성한다. 자동으로 생성한 mapping 모델을 사용해 데이터 구조를 바꿀 수 있다면 적용해 기존의 데이터를 새로운 모델로 이전하고, Stack을 초기화한다. 또한 이전 방식에 따라 다음의 조건을 따른다. Non-Optional Attr에서 Optional Attr로 이전하는 경우 제약이 존재..
200. Performance & Debugging Performance & debugging CoreData이 우수한 성능 덕분에 대부분의 개발자나 사용자의 요청을 처리하는 데에는 문제가 없다. Predicate가 난해한 경우 너무 많은 데이터를 불러오는 경우 Faults를 너무 자주 발생하는 경우 위의 세 경우를 감안해 요청을 생성한다면, CoreData의 데이터 처리에 필요한 시간을 획기적으로 개선할 수 있다. CoreData Debugging CoreData가 어느 부분에서 부하가 높은지 확인하기 위해서는 Xcode의 Scheme과 Instrument를 사용한다. Scheme Xcode의 상단에는 현재 프로젝트의 상태를 표시하는 공간이 존재한다. 여기서 프로젝트 이름을 누르면 위와 같은 팝업창이 표시되는데, 여기서 Edit Scheme을 선택해 L..
199. Context Synchronization Context Synchronization Context는 각자가 개별적으로 동작하므로, 동일한 Entity를 복수의 Context가 각자 처리하는 경우 데이터 무결성의 문제가 생긴다. 이러한 문제는 실제 값을 변경하게 되는 업데이트와 저장에서 더욱 두드러진다. 따라서 어떤 데이터를 적용할 건지, 옳은 데이터인지 판단할 Merge 정책이 필요하다. Main Context와 Background Context에서 같은 Entity의 같은 데이터에 접근한 뒤, Fetch, Update, Save를 진행해 차이를 확인하고, 동기화를 구현한다. SyncAndMergeViewController>fetchIntoMainContext() @IBAction func fetchIntoMainContext(_ sender:..
Stack #2 서론 이전에 정리했던 Stack의 구조와 동작 방식을 이해하고, 문제를 풀며 이를 응용해 본다. 본론 Q1 스택에 push 되는 값들이 오름차 수열이 되는지를 판단해, 불가하면 'NO'를 가능하다면 작업의 순서를 push는 '+'로 pop은 '-'로 출력하도록 하면 된다. Q1_Python Stack class Stack2(): class Empty(Exception): pass def __init__(self): self.stk = [] def is_empty(self) -> bool: return not self.stk def push(self, val): self.stk.append(val) def pop(self): if self.is_empty(): raise Stack2.Empty return..