From 39bf68b46ceae583d115f48166166fb6f7ca9c48 Mon Sep 17 00:00:00 2001 From: jihoonahn Date: Wed, 29 Nov 2023 17:07:58 +0000 Subject: [PATCH] deploy: d74064e1684e1eb3edb317251988aee611797fd8 --- blog/iga-ios-1/index.html | 4 +- blog/publish-introduce/index.html | 4 +- blog/publish-part-1/index.html | 4 +- blog/publish-part-2/index.html | 4 +- blog/scade-introduce/index.html | 2 +- blog/swiftui-need-mvvm/index.html | 4 +- blog/tuist-xcodebeta/index.html | 4 +- blog/universal-framework/index.html | 4 +- blog/what-is-swift/index.html | 4 +- blog/what-is-swiftui/index.html | 4 +- blog/yackety-yak-ios-4/index.html | 4 +- feed.rss | 2 +- static/icons/copy.svg | 1 + static/scripts/post.js | 23 +++++++++ styles.css | 74 +++++++++++++++++++++++++++++ tags/index.html | 2 +- 16 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 static/icons/copy.svg create mode 100644 static/scripts/post.js diff --git a/blog/iga-ios-1/index.html b/blog/iga-ios-1/index.html index 0f411aa1..47adbdcc 100644 --- a/blog/iga-ios-1/index.html +++ b/blog/iga-ios-1/index.html @@ -1,4 +1,4 @@ -제 1회 IGA 발표 회고록

제 1회 IGA 발표 회고록

IGA 발표 회고

이번 제 1회 iOS IGA에서 CLI 구축 방법에 대해서 발표를 했고, 이에 대한 회고 입니다.

발표 준비

발표 전 원래 주제로 "생산성으로 위한 Script"에 대해서 발표를 하려고 생각하고 있었습니다.

하지만 Swift로 작성하는 Script는 하나의 작업을 실행하기 위해서 Script에 많은 양의 코드가 들어가고, 중복되는 코드.. 등등 제작하는 것도 리소스가 많이 소비가 되는데, 하나의 작업을 위해서 제작이 되기 때문에 사람들이 사용할만한 이유가 부족하다고 생각이 되었습니다.

여러가지 방법을 찾아보다가 Swift Argument Parser라는 라이브러리를 보게 되었고, 오히려 지금 제가 추구하는 생산성은 CLI 쪽이 맞겠다 생각을 해서, 주제를 "생산성을 위한 CLI 구축"으로 바꾸게 되었습니다.

이번 발표에서는 좋은 예제를 만들고 싶어서, 고민을 많이 했습니다.

1. CLI의 장점을 잘 보여주기 위해서 전용 CLI 제작
+제 1회 IGA 발표 회고록

제 1회 IGA 발표 회고록

IGA 발표 회고

이번 제 1회 iOS IGA에서 CLI 구축 방법에 대해서 발표를 했고, 이에 대한 회고 입니다.

발표 준비

발표 전 원래 주제로 "생산성으로 위한 Script"에 대해서 발표를 하려고 생각하고 있었습니다.

하지만 Swift로 작성하는 Script는 하나의 작업을 실행하기 위해서 Script에 많은 양의 코드가 들어가고, 중복되는 코드.. 등등 제작하는 것도 리소스가 많이 소비가 되는데, 하나의 작업을 위해서 제작이 되기 때문에 사람들이 사용할만한 이유가 부족하다고 생각이 되었습니다.

여러가지 방법을 찾아보다가 Swift Argument Parser라는 라이브러리를 보게 되었고, 오히려 지금 제가 추구하는 생산성은 CLI 쪽이 맞겠다 생각을 해서, 주제를 "생산성을 위한 CLI 구축"으로 바꾸게 되었습니다.

이번 발표에서는 좋은 예제를 만들고 싶어서, 고민을 많이 했습니다.

1. CLI의 장점을 잘 보여주기 위해서 전용 CLI 제작
 2. ML이라는 주제를 더 잘 녹여 낼 수 있는 GPT CLI 제작
 

2개의 주제를 가지고 일주일 정도를 고민했습니다.
1번을 선택하면 발표주제를 더 깊게 설명할 수 있고, 2번을 선택하면 컨퍼런스 주제와 CLI에 대한 흥미를 더 줄 수 있지 않을까? 라고 생각을 했습니다.

결과적으로는 컨퍼런스 주제를 더 잘 녹여내자는 생각에 2번을 선택했습니다.

발표 시작

제 발표는 3번째였습니다.

처음 추영욱님이 먼저 나가셔서 오프닝을 시작했습니다. 오프닝때 부터 반응이 좋았었고, 오프닝이 끝난 후 저 이전 발표자 분이신 긱코드님이 나가셔서 발표를 진행하셨는데 너무 발표를 재밌게 잘하셔서 더 떨리더라고요 ㅎㅎ..

어느정도 떨긴 했지만 최대한 많은 내용을 전달하고자 하는 생각으로 발표를 시작하게 되었습니다.

발표는 다음 순서로 진행이 됬습니다.

1. CLI 제작기
 2. CLI vs Script
@@ -6,4 +6,4 @@
 4. 예시 프로젝트
 5. 저는 CLI를 이런 곳에 사용합니다.
 6. CLI가 사용되는 곳
-

1번, 2번에서는 목차에서 제가 CLI를 제작하게 된 계기를 위에 Script와 고민했던 것, 그리고 그 이후에 CLI를 제작하게 된 배경에 대해서 설명하고
3번째에는 Swift Argument Parser 사용 방법에 대해서 이야기 하고,
4번째에는 위에서 이야기한 CLI에서 GPT를 사용하는 예시 프로젝트에 대해서,
그리고 5번째는 CLI를 어디서 이용했는지에 대한 이야기를 하였고,
마지막은 대부분 iOS 개발자들이 알 수 있는 메이저한 라이브러리/프레임워크에서 어디에 사용됬는지에 대해서 이야기 했습니다.

느낀점

저번에 와글와글 iOS 발표를 하고, 이번에는 처음으로 오프라인 발표를 해봤지만.. 확실히 온라인 발표와 오프라인 발표는 뭐가 쉬웠다 이런게 아닌 두가지 느낌이 완전히 다르다고 느껴졌습니다.

와글와글때는 온라인에서 발표 전에는 진정이 많이 됬는데, 진행하는 도중에 떨리게 되었고, 이번에 진행한 IGA 오프라인 발표는 발표전에 오히려 많이 떨리고, 진행하면서 진정이 많이되는 느낌을 받았습니다.

발표를 2번 진행하면서 이번에도 몇번씩 실수를 하는것을 보며, 여전히 부족하다는 것을 깨닳게 되었고, 이번에는 CLI라는 주제가 Swift에서는 자주 발표하는 주제가 아닌 만큼, 걱정이 많이 됬었지만 오거나이저 분들과 스피커 분들도 다들 좋게 말해주셔서 다행이라고 생각이 되었습니다.

\ No newline at end of file +

1번, 2번에서는 목차에서 제가 CLI를 제작하게 된 계기를 위에 Script와 고민했던 것, 그리고 그 이후에 CLI를 제작하게 된 배경에 대해서 설명하고
3번째에는 Swift Argument Parser 사용 방법에 대해서 이야기 하고,
4번째에는 위에서 이야기한 CLI에서 GPT를 사용하는 예시 프로젝트에 대해서,
그리고 5번째는 CLI를 어디서 이용했는지에 대한 이야기를 하였고,
마지막은 대부분 iOS 개발자들이 알 수 있는 메이저한 라이브러리/프레임워크에서 어디에 사용됬는지에 대해서 이야기 했습니다.

느낀점

저번에 와글와글 iOS 발표를 하고, 이번에는 처음으로 오프라인 발표를 해봤지만.. 확실히 온라인 발표와 오프라인 발표는 뭐가 쉬웠다 이런게 아닌 두가지 느낌이 완전히 다르다고 느껴졌습니다.

와글와글때는 온라인에서 발표 전에는 진정이 많이 됬는데, 진행하는 도중에 떨리게 되었고, 이번에 진행한 IGA 오프라인 발표는 발표전에 오히려 많이 떨리고, 진행하면서 진정이 많이되는 느낌을 받았습니다.

발표를 2번 진행하면서 이번에도 몇번씩 실수를 하는것을 보며, 여전히 부족하다는 것을 깨닳게 되었고, 이번에는 CLI라는 주제가 Swift에서는 자주 발표하는 주제가 아닌 만큼, 걱정이 많이 됬었지만 오거나이저 분들과 스피커 분들도 다들 좋게 말해주셔서 다행이라고 생각이 되었습니다.

\ No newline at end of file diff --git a/blog/publish-introduce/index.html b/blog/publish-introduce/index.html index d27b5594..119127ac 100644 --- a/blog/publish-introduce/index.html +++ b/blog/publish-introduce/index.html @@ -1,4 +1,4 @@ -Publish 소개

Publish 소개

Swift로 Static Site 만들기

What is Publish

Publish는 John Sundell님이 만든 정적사이트 생성기 입니다.
Markdown Parser인 Ink와 Swift에서 HTML, XML, RSS를 작성하기 위한 DSL인 Plot을 사용합니다.

Swift Package로 제공되기 때문에 Package.swift 에 Dependency로 추가하여 사용할 수 있습니다.

let package = Package(
+Publish 소개

Publish 소개

Swift로 Static Site 만들기

What is Publish

Publish는 John Sundell님이 만든 정적사이트 생성기 입니다.
Markdown Parser인 Ink와 Swift에서 HTML, XML, RSS를 작성하기 위한 DSL인 Plot을 사용합니다.

Swift Package로 제공되기 때문에 Package.swift 에 Dependency로 추가하여 사용할 수 있습니다.

let package = Package(
     ...
     dependencies: [
         .package(url: "https://github.com/johnsundell/publish.git", from: "0.9.0")
@@ -18,4 +18,4 @@
 description: Welcome to publish.
 tags: publish, web, static site
 ---
-

markdown file 위에 정보를 입력해줍니다.
date는 언제 이 글을 작성했는지를 보여주고, description은 글에 대한 짧은 설명을 적습니다.

그리고 publish 에서는 tag기능을 제공합니다. 저기에 tag를 적어두면?

이렇게 https://localhost:8000/tags에 tag들이 추가 되고, tag를 누르면?

tag를 가지고 있는 글들을 조회할 수도 있습니다.


이번 글에서는 간단하게 publish에 대해서 소개하는 글을 적어봤습니다.
와글와글때 발표했던 내용이랑 중복되는 부분이 많았지만.. 다음 글에서는 publish 커스텀하는 방법, publish로 작성한 글 deploy 하기 등등 publish는 시리즈로 진행할 예정입니다.

\ No newline at end of file +

markdown file 위에 정보를 입력해줍니다.
date는 언제 이 글을 작성했는지를 보여주고, description은 글에 대한 짧은 설명을 적습니다.

그리고 publish 에서는 tag기능을 제공합니다. 저기에 tag를 적어두면?

이렇게 https://localhost:8000/tags에 tag들이 추가 되고, tag를 누르면?

tag를 가지고 있는 글들을 조회할 수도 있습니다.


이번 글에서는 간단하게 publish에 대해서 소개하는 글을 적어봤습니다.
와글와글때 발표했던 내용이랑 중복되는 부분이 많았지만.. 다음 글에서는 publish 커스텀하는 방법, publish로 작성한 글 deploy 하기 등등 publish는 시리즈로 진행할 예정입니다.

\ No newline at end of file diff --git a/blog/publish-part-1/index.html b/blog/publish-part-1/index.html index b4334b0a..abc18d21 100644 --- a/blog/publish-part-1/index.html +++ b/blog/publish-part-1/index.html @@ -1,4 +1,4 @@ -Publish 사용하기 part 1

Publish 사용하기 part 1

Swift publish 구조 살펴보기

Publish 구조 살펴보기

기존 처음 Publish 프로젝트를 생성하고, main.swift 코드입니다.

import Foundatio
+Publish 사용하기 part 1

Publish 사용하기 part 1

Swift publish 구조 살펴보기

Publish 구조 살펴보기

기존 처음 Publish 프로젝트를 생성하고, main.swift 코드입니다.

import Foundatio
 import Publish
 import Plot
 
@@ -89,4 +89,4 @@
     .generateRSSFeed(including: [.posts]),
     .generateSiteMap()
 ])
-

publish(using:) 메서드에서 pipeline을 하나하나 사용자가 원하는대로 지정할 수 있습니다.

위에서 진행한 내용은 예시코드 를 확인할 수 있습니다.


이번 글에서는 Publish 커스텀 중에서 구조를 이루는 부분에 대한 글을 적어봤습니다.
다음 글에서는 publish에서 HTML을 어떻게 작성하는지에 대한 내용을 작성할 예정입니다.

\ No newline at end of file +

publish(using:) 메서드에서 pipeline을 하나하나 사용자가 원하는대로 지정할 수 있습니다.

위에서 진행한 내용은 예시코드 를 확인할 수 있습니다.


이번 글에서는 Publish 커스텀 중에서 구조를 이루는 부분에 대한 글을 적어봤습니다.
다음 글에서는 publish에서 HTML을 어떻게 작성하는지에 대한 내용을 작성할 예정입니다.

\ No newline at end of file diff --git a/blog/publish-part-2/index.html b/blog/publish-part-2/index.html index 3df56075..0b0a21aa 100644 --- a/blog/publish-part-2/index.html +++ b/blog/publish-part-2/index.html @@ -1,4 +1,4 @@ -Publish 사용하기 part 2

Publish 사용하기 part 2

Swift publish 커스텀하기

Publish 구조 작성하기

struct PublishHTMLFactory: HTMLFactory {
+Publish 사용하기 part 2

Publish 사용하기 part 2

Swift publish 커스텀하기

Publish 구조 작성하기

struct PublishHTMLFactory: HTMLFactory {
     typealias Site = Example
 
     func makeIndexHTML(for index: Publish.Index, context: Publish.PublishingContext<Example>) throws -> Plot.HTML {
@@ -520,4 +520,4 @@
     taggedWith: page.tag,
     sortedBy: \.date
 ),
-

items를 가져오는 부분을 보면 context의 items를 가져오는데 page.tag가 포함되어 있는 item 만 가져오게 해준다라고 생각하시면 될것 같습니다.

이런식으로 Tag를 눌렀을때 잘 조회가 되는것을 확인할 수 있습니다. 이렇게 해서 저희는 Publish로 웹사이트 하나를 뚝딱 만들어 봤습니다.

위에서 진행한 내용은 예시코드 를 확인할 수 있습니다.


이번 글에서는 Publish에서 HTML을 작성하는 방법과, 직접 예제를 만들어보며 Publish를 이용해서 실질적인 웹사이트를 만들어 봤습니다.

다음글에서는 Publish로 만든 웹사이트를 배포하는 법에 대해서 작성할 예정입니다.

\ No newline at end of file +

items를 가져오는 부분을 보면 context의 items를 가져오는데 page.tag가 포함되어 있는 item 만 가져오게 해준다라고 생각하시면 될것 같습니다.

이런식으로 Tag를 눌렀을때 잘 조회가 되는것을 확인할 수 있습니다. 이렇게 해서 저희는 Publish로 웹사이트 하나를 뚝딱 만들어 봤습니다.

위에서 진행한 내용은 예시코드 를 확인할 수 있습니다.


이번 글에서는 Publish에서 HTML을 작성하는 방법과, 직접 예제를 만들어보며 Publish를 이용해서 실질적인 웹사이트를 만들어 봤습니다.

다음글에서는 Publish로 만든 웹사이트를 배포하는 법에 대해서 작성할 예정입니다.

\ No newline at end of file diff --git a/blog/scade-introduce/index.html b/blog/scade-introduce/index.html index 4dfb4cd3..0ac53280 100644 --- a/blog/scade-introduce/index.html +++ b/blog/scade-introduce/index.html @@ -1 +1 @@ -Scade 소개

Scade 소개

Swift로 크로스플랫폼 만드는 방법을 아시나요?

What is Scade?

Swift로 iOS 와 Android 개발을 동시에 할 수 있는 크로스 플랫폼입니다.

scade.io

전용 툴을 제공하며, 위 링크에서 다운 받을 수 있다.
Scade의 공식문서 입니다.


어떻게 동작되는 걸까?

Swift코드를 네이티브 iOS와 Android를 바이너리로 컴파일하여, 앱을 빌드합니다.
현재 기준 Scade는 Swift 5.4를 지원합니다.

위 링크를 통해 전용 툴을 다운로드 받았다면

이러한 어플리케이션을 확인할 수 있을겁니다.

그리고 Xcode와 AndroidStudio 설치까지 마치셨다면, 공식문서를 보고 세팅해주시면 됩니다.

중요

이 부분의 세팅할 때 주의하시는 것이 좋습니다.

프로젝트 생성하기

IDE 내부에서 FILE| Name | New Project 로 프로젝트를 생성해줍니다.

스크린샷 2023-03-18 오후 3 38 06스크린샷 2023-03-18 오후 3 38 20

Scade IDE에서 프로젝트를 생성해주면 됩니다.

Scade같은 경우 3가지 종류의 로 빌드가 가능합니다.
자체 시뮬레이터인 Scade Simulator, iOS의 Simulator, Android Emulator

뷰 같은 경우 .page 파일에서 스토리보드와 비슷하게 되어 있는것을 확인 할 수 있고,

우측 + 버튼을 눌러서 Component를 가져올 수 있습니다.

원하는 컴포넌트를 Drag & Drop 해주면 됩니다. (Storyboard와 같은 느낌이죠?)

Scade IDE 우측에 있는 옵션들을 수정하여, Component를 설정 할 수도 있습니다.

실행

한번 Android와 iOS에서 잘 돌아가는지 확인해 보겠습니다.

좌 iOS Simulator, 우 Android Emulator

같은 UI로 잘 돌아가는 것을 확인 할 수 있습니다.

Scade를 사용해보고 느낀점

현재 꾸준히 개발되고 있지만 현재는 Beta 버전이고, 현재 공개된 Scade Platform Github는 이곳입니다. 아쉽게도 Scade SDK는 오픈소스는 아니기 때문에 뭔가 아쉽다 라는 느낌을 받긴 했지만, Swift로 iOS, Android CrossPlatform 개발이 된다는 점에서 신기한 느낌을 받고, IDE에서 Storyboard와 같은 기능을 지원하는것도 신기했습니다.

아직 부족한 부분은 분명 있지만 현재 베타버전임을 감안하고, 몇년에 걸쳐서 개발이 되는것을 보아,
추후 정식 출시날도 기다려집니다.

제가 개인적으로 느낀 점은, 그저 신기하다에 그치지 않고 Scade는 생각보다 놀라운 도구 였습니다.

저의 주 언어인 Swift를 가지고 Android 와 iOS를 동시 개발 가능하게 해주기 때문에, 저에게는 큰 흥미를 주었던 것 같습니다.

현재 Scade의 미래가 어떻게 될지 모르지만 Scade는 Beta에서만 끝나지 않고, 늦어도 좋으니 정식 출시까지 했으면 좋겠다는 생각이 들었습니다. (추후 Apple에서 비슷한 걸 제공해도 좋고요 ㅎㅎ)



이번에는 Scade에 대해서 소개하는 글이기 때문에, 간단하게 소개했기 때문에 여기에서 글을 끝내고
나중에 Scade를 더 깊게 사용해보며, 글을 적도록 하겠습니다.

\ No newline at end of file +Scade 소개

Scade 소개

Swift로 크로스플랫폼 만드는 방법을 아시나요?

What is Scade?

Swift로 iOS 와 Android 개발을 동시에 할 수 있는 크로스 플랫폼입니다.

scade.io

전용 툴을 제공하며, 위 링크에서 다운 받을 수 있다.
Scade의 공식문서 입니다.


어떻게 동작되는 걸까?

Swift코드를 네이티브 iOS와 Android를 바이너리로 컴파일하여, 앱을 빌드합니다.
현재 기준 Scade는 Swift 5.4를 지원합니다.

위 링크를 통해 전용 툴을 다운로드 받았다면

이러한 어플리케이션을 확인할 수 있을겁니다.

그리고 Xcode와 AndroidStudio 설치까지 마치셨다면, 공식문서를 보고 세팅해주시면 됩니다.

중요

이 부분의 세팅할 때 주의하시는 것이 좋습니다.

프로젝트 생성하기

IDE 내부에서 FILE| Name | New Project 로 프로젝트를 생성해줍니다.

스크린샷 2023-03-18 오후 3 38 06스크린샷 2023-03-18 오후 3 38 20

Scade IDE에서 프로젝트를 생성해주면 됩니다.

Scade같은 경우 3가지 종류의 로 빌드가 가능합니다.
자체 시뮬레이터인 Scade Simulator, iOS의 Simulator, Android Emulator

뷰 같은 경우 .page 파일에서 스토리보드와 비슷하게 되어 있는것을 확인 할 수 있고,

우측 + 버튼을 눌러서 Component를 가져올 수 있습니다.

원하는 컴포넌트를 Drag & Drop 해주면 됩니다. (Storyboard와 같은 느낌이죠?)

Scade IDE 우측에 있는 옵션들을 수정하여, Component를 설정 할 수도 있습니다.

실행

한번 Android와 iOS에서 잘 돌아가는지 확인해 보겠습니다.

좌 iOS Simulator, 우 Android Emulator

같은 UI로 잘 돌아가는 것을 확인 할 수 있습니다.

Scade를 사용해보고 느낀점

현재 꾸준히 개발되고 있지만 현재는 Beta 버전이고, 현재 공개된 Scade Platform Github는 이곳입니다. 아쉽게도 Scade SDK는 오픈소스는 아니기 때문에 뭔가 아쉽다 라는 느낌을 받긴 했지만, Swift로 iOS, Android CrossPlatform 개발이 된다는 점에서 신기한 느낌을 받고, IDE에서 Storyboard와 같은 기능을 지원하는것도 신기했습니다.

아직 부족한 부분은 분명 있지만 현재 베타버전임을 감안하고, 몇년에 걸쳐서 개발이 되는것을 보아,
추후 정식 출시날도 기다려집니다.

제가 개인적으로 느낀 점은, 그저 신기하다에 그치지 않고 Scade는 생각보다 놀라운 도구 였습니다.

저의 주 언어인 Swift를 가지고 Android 와 iOS를 동시 개발 가능하게 해주기 때문에, 저에게는 큰 흥미를 주었던 것 같습니다.

현재 Scade의 미래가 어떻게 될지 모르지만 Scade는 Beta에서만 끝나지 않고, 늦어도 좋으니 정식 출시까지 했으면 좋겠다는 생각이 들었습니다. (추후 Apple에서 비슷한 걸 제공해도 좋고요 ㅎㅎ)



이번에는 Scade에 대해서 소개하는 글이기 때문에, 간단하게 소개했기 때문에 여기에서 글을 끝내고
나중에 Scade를 더 깊게 사용해보며, 글을 적도록 하겠습니다.

\ No newline at end of file diff --git a/blog/swiftui-need-mvvm/index.html b/blog/swiftui-need-mvvm/index.html index f487c6c1..152fbc41 100644 --- a/blog/swiftui-need-mvvm/index.html +++ b/blog/swiftui-need-mvvm/index.html @@ -1,4 +1,4 @@ -SwiftUI에 MVVM이 필요할까요?

SwiftUI에 MVVM이 필요할까요?

요즘 이슈가 되고 있는 내용으로, 과연 SwiftUI에는 MVVM이 필요한지에 대한 저의 주관적인 생각을 담은 글입니다.

SwiftUI MVVM issue?

Stop using MVVM for SwiftUI (apple developer forms)
Stop using MVVM with SwiftUI (medium post)

위 글을 보면 SwiftUI에서 MVVM 사용을 멈추자는 의견을 제시하고 있습니다.

“SwiftUI에서 MVVM 사용 중지”라는 강력한 주제로 저의 관심을 끌었습니다.

글은 꽤나 논리적인 글이라고 생각이 되었습니다. SwiftUI내에서 MVVM의 사용을 의심하지 않았던 저에게는 진짜 많은 생각을 하게 만들었었습니다.

Is MVVM an anti-pattern in SwiftUI?

Reddit에서도 issue가 된 내용입니다.


여기서부터는 저의 생각이 들어갔습니다.

SwiftUI는? 선언형 뷰 프로그래밍 방식입니다.

선언형 UI에서는 ViewModel은 필요할까 라는 주제의 여러 글들을 보고 따로 공부와 여러가지 생각을 했습니다.

옛날에는 “MVVM이 무조건 좋다” 라는 인식이 존재했습니다. 그런데 SwiftUI로 개발을 하면서 억지로 ViewModel을 만드는 상황이 발생하고 있습니다.

ViewModel은 비즈니스 로직을 분리하는 목적으로 사용할 수 있기 때문에 ViewModel이 완전히 나쁘다 라고 하기는 어려울것 같습니다.
하지만 저는 SwiftUI의 View는 이미 View + ViewModel라고 생각하기 때문에 저는 불필요하다고 생각합니다.

SwiftUI에서의 View는 이미 View+ViewModel 입니다.

import SwiftUI
+SwiftUI에 MVVM이 필요할까요?

SwiftUI에 MVVM이 필요할까요?

요즘 이슈가 되고 있는 내용으로, 과연 SwiftUI에는 MVVM이 필요한지에 대한 저의 주관적인 생각을 담은 글입니다.

SwiftUI MVVM issue?

Stop using MVVM for SwiftUI (apple developer forms)
Stop using MVVM with SwiftUI (medium post)

위 글을 보면 SwiftUI에서 MVVM 사용을 멈추자는 의견을 제시하고 있습니다.

“SwiftUI에서 MVVM 사용 중지”라는 강력한 주제로 저의 관심을 끌었습니다.

글은 꽤나 논리적인 글이라고 생각이 되었습니다. SwiftUI내에서 MVVM의 사용을 의심하지 않았던 저에게는 진짜 많은 생각을 하게 만들었었습니다.

Is MVVM an anti-pattern in SwiftUI?

Reddit에서도 issue가 된 내용입니다.


여기서부터는 저의 생각이 들어갔습니다.

SwiftUI는? 선언형 뷰 프로그래밍 방식입니다.

선언형 UI에서는 ViewModel은 필요할까 라는 주제의 여러 글들을 보고 따로 공부와 여러가지 생각을 했습니다.

옛날에는 “MVVM이 무조건 좋다” 라는 인식이 존재했습니다. 그런데 SwiftUI로 개발을 하면서 억지로 ViewModel을 만드는 상황이 발생하고 있습니다.

ViewModel은 비즈니스 로직을 분리하는 목적으로 사용할 수 있기 때문에 ViewModel이 완전히 나쁘다 라고 하기는 어려울것 같습니다.
하지만 저는 SwiftUI의 View는 이미 View + ViewModel라고 생각하기 때문에 저는 불필요하다고 생각합니다.

SwiftUI에서의 View는 이미 View+ViewModel 입니다.

import SwiftUI
 
 struct Content: View {
     @State var model = Themes.listModel
@@ -16,4 +16,4 @@
 }
 

medium 블로그 글의 예시를 가져왔습니다.

예시처럼 SwiftUI의 View는 원래부터 데이터 바인딩 기능을 포함하고 있기 때문에, 모델 값을 View에 직접 Reactive하게 반영 할 수 있습니다.

ViewModel은 원래 상태를 View에 Binding하여 Reactive에 반영하기 위한 목적으로 도입되었습니다.

하지만 위 예시처럼 선언적 UI에는 해당 기능이 포함되어 있으므로 ViewModel은 필요하지 않다고 생각합니다.


우리가 왜 MVVM이 무조건 좋다고 생각했을까요?

이것은 기존 사용했던 UIKit을 보고 알 수 있었습니다.

기존 코드에서는 rx를 통해 데이터 바인딩을 해주는 코드를 사용했습니다. (RxSwift를 사용했을 때) 흔하게 알고 있는 ViewModel을 통해서 뷰와 데이터 바인딩을 해주는 MVVM 구조입니다.

ViewModel의 가장 중요한 역할은 데이터 바인딩입니다. 모델과 뷰 사이에 양방향 통신을 해주면서 바인딩을 시켜줍니다.

하지만 SwiftUI에서는 View에서 다 해줄 수 있기 때문에 필요가 없다는 생각이 됩니다.


SwiftUI에 MVVM을 사용하는 것은 복잡도를 올리게 됩니다.

SwiftUI에서 MVVM을 사용하게 되면, ViewModel이라는 레이어가 추가되기 때문에 복잡도가 증가합니다.

또한 Data Flow는 ViewModel이 View와 Model의 중간 레이어와 함께 배치되어서 양방향으로 동작하게 됩니다.

my-option

Apple Document

선언형 UI를 사용하는 환경에서는 단방향 데이터 플로우 구조를 지향합니다.

현재 많은 개발자들이 아키텍처 패턴으로 MVVM을 사용합니다.

많은 자료들이 SwiftUI + MVVM을 사용하는 방법에 대해서 설명을 하고 있기도 합니다.


이미 Vue나 React, Flutter 모두 MVVM을 사용하고 있지 않습니다.

세가지의 모두 공통점으로 선언형 UI를 사용한다는 것을 알 수 있습니다.

그러면 MVVM 말고 SwiftUI에서 무엇을 사용해야 할까요?

그럼 뭘 사용하라는 건가

ViewModel을 사용하지 않는다면 비즈니스 로직과 UI 로직을 어떻게 어디서 분리해야 할까요?

Realm에서는 MVI 접근 방식을 지향한다고 합니다.

3가지 방법을 생각해볼 수 있습니다.

  1. Model에서 이를 구현한다. (MV)
  2. MVI (Model-View-Intent)
  3. Flux 개념의 Store로 분리한다.

첫번째 방법은 선언적 UI에 어울리는 단방향 플로우의 장점을 챙겨가지 못하기 때문에 적합하지 않고,

그렇기 때문에 MVI 와 Flux 및 Store/Provider 패턴이 적합하다고 생각합니다.


저는 이 논쟁에 대해 저의 생각을 답글에 달았습니다.

my-option -
\ No newline at end of file +
\ No newline at end of file diff --git a/blog/tuist-xcodebeta/index.html b/blog/tuist-xcodebeta/index.html index ca2ccad0..7c4d5710 100644 --- a/blog/tuist-xcodebeta/index.html +++ b/blog/tuist-xcodebeta/index.html @@ -1,4 +1,4 @@ -Xcode-Beta에서 Tuist 사용기

Xcode-Beta에서 Tuist 사용기

Xcode Beta에서 tuist edit 명령어에서 에러나는 부분을 해결하는 방법에 대한 포스트입니다.

Beta를 사용했을때

최근에 WWDC23이 공개되었습니다. macOS에서 발표된 내용을 보고 macOS 14와 Xcode 15의 변화에 대해서 보기 위해서, 업데이트를 했습니다.

그렇게 봉인된.. Xcode..

macOS 14에서는 기존 Xcode 14.3.1(글 작성 기준)를 사용하지 못하게 됩니다.
그래서 Xcode 15를 설치해야합니다.

Xcode 설치 링크

어떤 문제가 있었나..

그렇게, Xcode 15를 설치하고 Tuist를 실행 했을 때, 이런 문제가 있더군요. Tuist에서 tuist edit 명령어를 실행했을 때,

이런 식으로 실행이 안되는 문제가 있었습니다.
이유는.. 위에서 빌드업 했지만, 문제는 Tuist Command Service 부분에 있었습니다.

문제는 어디서?

try opener.open(path: workspacePath, application: selectedXcode.path, wait: true)
+Xcode-Beta에서 Tuist 사용기

Xcode-Beta에서 Tuist 사용기

Xcode Beta에서 tuist edit 명령어에서 에러나는 부분을 해결하는 방법에 대한 포스트입니다.

Beta를 사용했을때

최근에 WWDC23이 공개되었습니다. macOS에서 발표된 내용을 보고 macOS 14와 Xcode 15의 변화에 대해서 보기 위해서, 업데이트를 했습니다.

그렇게 봉인된.. Xcode..

macOS 14에서는 기존 Xcode 14.3.1(글 작성 기준)를 사용하지 못하게 됩니다.
그래서 Xcode 15를 설치해야합니다.

Xcode 설치 링크

어떤 문제가 있었나..

그렇게, Xcode 15를 설치하고 Tuist를 실행 했을 때, 이런 문제가 있더군요. Tuist에서 tuist edit 명령어를 실행했을 때,

이런 식으로 실행이 안되는 문제가 있었습니다.
이유는.. 위에서 빌드업 했지만, 문제는 Tuist Command Service 부분에 있었습니다.

문제는 어디서?

try opener.open(path: workspacePath, application: selectedXcode.path, wait: true)
 

tuist > Sources > TuistKit > Services > EditService.swift 의 78번째 줄

위 코드 부분에서 에러가 발생합니다.

Xcode 앱을 실행시키는 코드이고, 현재 Xcode는 위 그림처럼 봉인(?)당했기 때문에 Xcode앱을 열 수 없는 것입니다.

나머지 명령어에서는 문제가 없었지만, tuist edit 명령어에서만 문제가 생기더라고요.
이 문제에 대한 해결 방법은 없을까요?

해결 방법

1. Tuist 명령어만으로 해결하는 방법

tuist edit -h를 실행시켜 명령어를 찾아봅시다.

Tuist 공식 깃허브 코드에서는 permanent가 true면, Xcode앱을 실행시키지 않습니다.

let workspacePath = try projectEditor.edit(
     at: path,
     in: path,
@@ -27,4 +27,4 @@
     selectedXcode = xcode
     return xcode
 }
-

근데 처음에 시도할때는 xcode-select 명령어의 option에서 path를 따로 바꿀 수 있다는 사실을 망각하고 있었기 때문에, 다양한 방식을 찾은 거 같습니다.

어쨋든 Xcode-beta 또는 다른 버전의 Xcode 앱을 설치하고 tuist edit 명령어가 작동하지 않아서 당황하신 분들을 위해서 이 글을 적었습니다.

이 방식 외 더 좋은 방식에 대해서 알고 계신 분이 있다면, blog 댓글에 알려주세요.

\ No newline at end of file +

근데 처음에 시도할때는 xcode-select 명령어의 option에서 path를 따로 바꿀 수 있다는 사실을 망각하고 있었기 때문에, 다양한 방식을 찾은 거 같습니다.

어쨋든 Xcode-beta 또는 다른 버전의 Xcode 앱을 설치하고 tuist edit 명령어가 작동하지 않아서 당황하신 분들을 위해서 이 글을 적었습니다.

이 방식 외 더 좋은 방식에 대해서 알고 계신 분이 있다면, blog 댓글에 알려주세요.

\ No newline at end of file diff --git a/blog/universal-framework/index.html b/blog/universal-framework/index.html index 5ec54475..45faa1d4 100644 --- a/blog/universal-framework/index.html +++ b/blog/universal-framework/index.html @@ -1,4 +1,4 @@ -Universal Framework

Universal Framework

Universal Framework에 대한 공부

Universal Framework (범용 프레임워크)

디바이스와 시뮬레이터에서 사용가능하도록 범용적으로 프레임워크를 만드는 것입니다.
Device에서의 OS, SimulatorOS 둘 모두에 적용하기 위해서는 Valid Architecture가 모두 존재해야합니다. iPhone OS에서의 CPU와, macOS에서의 경우 시뮬레이터의 구동을 위해서는 macOS의 CPU가 구현되어 맞춰줘야 합니다.

이러한 문제점을 해결하기 위해서 나온 것이 Universal Framework입니다.

Universal Framework 의 장점

  • 코드 재사용성이 올라간다.
  • 코드 숨기가 쉬워진다.
  • 코드 모듈화에 이점을 갖는다.
  • 쉬운 통합이 가능하다.
  • 쉽게 배포할 수 있다.

사용법

Target 아래쪽에 있는 + 버튼을 누릅니다. 그 후 Other -> Aggregate를 추가합니다. (Framework와 XCFramework 둘다 생성해줍니다.)


Add Script

각각의 Aggregate에 Script를 추가해줍니다.

XCFramework

# Build Device and Simulator versions
+Universal Framework

Universal Framework

Universal Framework에 대한 공부

Universal Framework (범용 프레임워크)

디바이스와 시뮬레이터에서 사용가능하도록 범용적으로 프레임워크를 만드는 것입니다.
Device에서의 OS, SimulatorOS 둘 모두에 적용하기 위해서는 Valid Architecture가 모두 존재해야합니다. iPhone OS에서의 CPU와, macOS에서의 경우 시뮬레이터의 구동을 위해서는 macOS의 CPU가 구현되어 맞춰줘야 합니다.

이러한 문제점을 해결하기 위해서 나온 것이 Universal Framework입니다.

Universal Framework 의 장점

  • 코드 재사용성이 올라간다.
  • 코드 숨기가 쉬워진다.
  • 코드 모듈화에 이점을 갖는다.
  • 쉬운 통합이 가능하다.
  • 쉽게 배포할 수 있다.

사용법

Target 아래쪽에 있는 + 버튼을 누릅니다. 그 후 Other -> Aggregate를 추가합니다. (Framework와 XCFramework 둘다 생성해줍니다.)


Add Script

각각의 Aggregate에 Script를 추가해줍니다.

XCFramework

# Build Device and Simulator versions
 xcodebuild archive -scheme "${PROJECT_NAME}" -archivePath "${BUILD_DIR}/iphoneos.xcarchive" -sdk iphoneos SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
 xcodebuild archive -scheme "${PROJECT_NAME}" -archivePath "${BUILD_DIR}/iphonesimulator.xcarchive" -sdk iphonesimulator SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
 
@@ -37,4 +37,4 @@
   
 # Open the project directory in Finder
 open "${PROJECT_DIR}"
-

Run

각각 원하는 Aggregate Scheme를 선택하고 빌드하면 됩니다.

좌 Framework Aggregate로 빌드 했을 때, 우 XCFramework Aggregate로 빌드 했을 때


Reference

\ No newline at end of file +

Run

각각 원하는 Aggregate Scheme를 선택하고 빌드하면 됩니다.

좌 Framework Aggregate로 빌드 했을 때, 우 XCFramework Aggregate로 빌드 했을 때


Reference

\ No newline at end of file diff --git a/blog/what-is-swift/index.html b/blog/what-is-swift/index.html index ac870514..a998a1c3 100644 --- a/blog/what-is-swift/index.html +++ b/blog/what-is-swift/index.html @@ -1,2 +1,2 @@ -Swift란?

Swift란?

Swift 언어에 대한 소개입니다.

Apple 공식 Swift

스위프트는 iOS, macOS, watchOS, tvOS를 개발하기 위해 애플에서 제공하는 프로그래밍 언어 입니다.

Swift의 특징

애플이 최초에 스위프트를 발표했을 때 스위프트 언어의 특성을 Safe, Modern, Powerful 이라고 발표했습니다. 그러나 오픈소스로 전환되면서 특징을 Safe, Fast, Expressive로 변경하여 발표했습니다. 더불어 애플은 ‘스위프트는 보다 직관적이고 배우기 쉬운 언어’라고 스위프트를 소개했습니다. 먼저 애플이 발표한 스위프트의 언어적 특성을 항목별로 정리해 보았습니다.

Safe

스위프트는 안전한 프로그래밍을 지향합니다.

소프트웨어가 배포되기 전에, 즉 프로그래밍을 하는 중에 프로그래머가 저지를 수 있는 실수를 엄격한 문법을 통하여 미연에 방지하고자 노력했습니다. 때론 너무 강제적이라고 느껴질 수 있지만 문법적 제재는 실수를 줄이는 데 도움이 됩니다. 버그를 수정하거나 실수를 찾아내는 시간을 절약할 수 있습니다.

옵셔널이라는 기능을 비롯하여 guard 구문, 오류처리, 강력한 타입통제 등을 통해 스위프트는 안전한 프로그래밍을 구현하고 있습니다.

Fast

스위프트는 C 언어를 기반으로 한 C, C++, Objective-C와 같은 프로그래밍 언어를 대체하려는 목적으로 만들어졌습니다. 아직은 부분적으로 미흡하지만 성능 또한 C 언어 수준을 목표로 개발되었습니다. 그래서 스위프트는 성능을 예측할 수 있고 일정한 수준으로 유지할 수 있는 부분에 초점을 맞춰 개발되었습니다.

실행속도의 최적화 뿐만 아니라 컴파일러의 지속된 개량을 통해 더 빠른 컴파일 성능을 구현해 나가고 있습니다.

Expressive

스위프트는 여러 가지 프로그래밍 패러다임을 채용한 다중 패러다임 프로그래밍 언어입니다. 크게 보면 스위프트는 명령형 프로그래밍 패러다임, 객체지향 프로그래밍 패러다임, 함수형 프로그래밍 패러다임, 프로토콜 지향 프로그래밍 패러다임을 지향합니다. 정확하게는 명령형과 객체지향 프로그래밍 패러다임을 기반으로 한 함수형 프로그래밍 패러다임과 프로토콜 지향 프로그래밍 패러다임을 지향합니다. 결과적으로 스위프트에서 가장 강조하는 부분은 함수형 프로그래밍 패러다임과 프로토콜 지향 프로그래밍 패러다임입니다.

기존의 C 언어는 명령형 혹은 절자적 프로그래밍 패러다임을 채용했으며, C++, Java 등의 언어는 명령형 프로그래밍 패러다임과 객체지향 프로그래밍 패러다임을 동시에 채용한 다중 프로그래밍 패러다임 언어입니다.

최신 업데이트는 5.7입니다.

Xcode Start

Xcode는 iOS App 개발을 위한 IDE(통합 개발 환경, Integrated Development Environment) 입니다. iOS 뿐만 아니라 macOS, iPadOS, tvOS, watchOS... 등등 다양판 플랫폼을 제공할 수 있다.

AppStore

또는

명령어를 통해서 설치할 수 있습니다.

xcode-select --install
-
\ No newline at end of file +Swift란?

Swift란?

Swift 언어에 대한 소개입니다.

Apple 공식 Swift

스위프트는 iOS, macOS, watchOS, tvOS를 개발하기 위해 애플에서 제공하는 프로그래밍 언어 입니다.

Swift의 특징

애플이 최초에 스위프트를 발표했을 때 스위프트 언어의 특성을 Safe, Modern, Powerful 이라고 발표했습니다. 그러나 오픈소스로 전환되면서 특징을 Safe, Fast, Expressive로 변경하여 발표했습니다. 더불어 애플은 ‘스위프트는 보다 직관적이고 배우기 쉬운 언어’라고 스위프트를 소개했습니다. 먼저 애플이 발표한 스위프트의 언어적 특성을 항목별로 정리해 보았습니다.

Safe

스위프트는 안전한 프로그래밍을 지향합니다.

소프트웨어가 배포되기 전에, 즉 프로그래밍을 하는 중에 프로그래머가 저지를 수 있는 실수를 엄격한 문법을 통하여 미연에 방지하고자 노력했습니다. 때론 너무 강제적이라고 느껴질 수 있지만 문법적 제재는 실수를 줄이는 데 도움이 됩니다. 버그를 수정하거나 실수를 찾아내는 시간을 절약할 수 있습니다.

옵셔널이라는 기능을 비롯하여 guard 구문, 오류처리, 강력한 타입통제 등을 통해 스위프트는 안전한 프로그래밍을 구현하고 있습니다.

Fast

스위프트는 C 언어를 기반으로 한 C, C++, Objective-C와 같은 프로그래밍 언어를 대체하려는 목적으로 만들어졌습니다. 아직은 부분적으로 미흡하지만 성능 또한 C 언어 수준을 목표로 개발되었습니다. 그래서 스위프트는 성능을 예측할 수 있고 일정한 수준으로 유지할 수 있는 부분에 초점을 맞춰 개발되었습니다.

실행속도의 최적화 뿐만 아니라 컴파일러의 지속된 개량을 통해 더 빠른 컴파일 성능을 구현해 나가고 있습니다.

Expressive

스위프트는 여러 가지 프로그래밍 패러다임을 채용한 다중 패러다임 프로그래밍 언어입니다. 크게 보면 스위프트는 명령형 프로그래밍 패러다임, 객체지향 프로그래밍 패러다임, 함수형 프로그래밍 패러다임, 프로토콜 지향 프로그래밍 패러다임을 지향합니다. 정확하게는 명령형과 객체지향 프로그래밍 패러다임을 기반으로 한 함수형 프로그래밍 패러다임과 프로토콜 지향 프로그래밍 패러다임을 지향합니다. 결과적으로 스위프트에서 가장 강조하는 부분은 함수형 프로그래밍 패러다임과 프로토콜 지향 프로그래밍 패러다임입니다.

기존의 C 언어는 명령형 혹은 절자적 프로그래밍 패러다임을 채용했으며, C++, Java 등의 언어는 명령형 프로그래밍 패러다임과 객체지향 프로그래밍 패러다임을 동시에 채용한 다중 프로그래밍 패러다임 언어입니다.

최신 업데이트는 5.7입니다.

Xcode Start

Xcode는 iOS App 개발을 위한 IDE(통합 개발 환경, Integrated Development Environment) 입니다. iOS 뿐만 아니라 macOS, iPadOS, tvOS, watchOS... 등등 다양판 플랫폼을 제공할 수 있다.

AppStore

또는

명령어를 통해서 설치할 수 있습니다.

xcode-select --install
+
\ No newline at end of file diff --git a/blog/what-is-swiftui/index.html b/blog/what-is-swiftui/index.html index cd70f49c..e5cecf2a 100644 --- a/blog/what-is-swiftui/index.html +++ b/blog/what-is-swiftui/index.html @@ -1,4 +1,4 @@ -SwiftUI 소개

SwiftUI 소개

선언형 UI로 생산성을 높여주는 SwiftUI에 대한 설명입니다.

본 영상은 WWDC 19이며 SwiftUI 소개되는 부분에서 시작이됩니다.

2019년 애플의 WWDC에서 처음 소개된 SwiftUI 는 모든 애플 운영체제용 앱을 개발하는데 있어서 완전히 새로운 방법을 제공합니다.

SwiftUI의 기본적인 목적은 앱 개발을 더 쉽고 폭발적인 생산성을 내면서 동시에 소프트웨어를 개발할 때 일반적으로 발생하는 버그들을 줄이는 것입니다.
또한 개발 과정에서도 앱의 라이브 프리뷰 기능을 이용하여 SwiftUI 프로젝트를 실시간으로 테스트할 수 있게 합니다.

위 이미지는 SwiftUI Project를 생성했을 때의 모습입니다.

SwiftUI의 선언적 구문

import SwiftUI
+SwiftUI 소개

SwiftUI 소개

선언형 UI로 생산성을 높여주는 SwiftUI에 대한 설명입니다.

본 영상은 WWDC 19이며 SwiftUI 소개되는 부분에서 시작이됩니다.

2019년 애플의 WWDC에서 처음 소개된 SwiftUI 는 모든 애플 운영체제용 앱을 개발하는데 있어서 완전히 새로운 방법을 제공합니다.

SwiftUI의 기본적인 목적은 앱 개발을 더 쉽고 폭발적인 생산성을 내면서 동시에 소프트웨어를 개발할 때 일반적으로 발생하는 버그들을 줄이는 것입니다.
또한 개발 과정에서도 앱의 라이브 프리뷰 기능을 이용하여 SwiftUI 프로젝트를 실시간으로 테스트할 수 있게 합니다.

위 이미지는 SwiftUI Project를 생성했을 때의 모습입니다.

SwiftUI의 선언적 구문

import SwiftUI
 
 struct ContentView: View {
     var body: some View {
@@ -51,4 +51,4 @@
         .background(.black)
     }
 }
-

같은 동작을 하는 뷰를 만들어 봤습니다.

차이점이 보이시나요? UIKit(명령형)과 SwiftUI(선언형)을 비교해볼 때

UIKit에서는 Property를 선언 view에 추가하고, Layout에 제약사항을 준 후, action을 할 함수를 만들어서 button에 addTarget 해줍니다.

하지만 SwiftUI에서는 그래로 원하는 위치에 Button을 추가하고 action을 추가하면 끝납니다.

생산성 부분에서 어마어마하게 차이가 난다는 걸 볼 수 있습니다.

UIKit과 SwiftUI를 함께 사용하는 방법

사실 UIView와 SwiftUI를 함께 사용할 수 있는 방법은 다양하게 존재합니다.

SwiftUI는 빠르고 효율적인 앱 개발 환경을 제공할 뿐만 아니라 코드를 크게 변경하지 않아도 다양한 애플 플랫폼에서 동일한 앱을 사용할 수 있게 합니다.

하지만 지도 또는 웹 뷰를 통합해야 하는 특정 기능은 여전히 UIKit을 사용해야 하고, 매우 복잡한 UI 레이아웃을 설계하는 경우에 SwiftUI 레이아웃 컨테이너 뷰 사용이 만족스럽지 않을 수 있습니다.

이런 상황에서는 인터페이스 빌더를 사용을 하는 방식으로 해결할 수도 있습니다.

지금 SwiftUI는 어떨까?

현재까지는 시기상조라는 말도 있고, 회사에서 도입 할 것이라는 말이 있습니다.
이 부분은 사람마다 의견이 다르기 때문에 정확한 대답은 어렵지만, 개인적으로 저는 자신이 처한 상황에서 직접 고려하여 결정하는 것이 좋다고 생각합니다.

SwiftUI 최소 버전은 iOS 기준 13.0이지만, 제대로 사용하려면 15.0 이상이여야 하기 때문에, 이러한 부분은 좀 많이 아쉽긴 합니다.

그리고 현재 SwiftUI는 버그도 있기도 하고, 아직 사용하기에는 불완전하다는 말에 동의는 합니다.
하지만 엄청난 생산성을 갖는다는것, 그리고 Apple이 추구하는 방향성의 UI Framework라는 것은 부정할 수 없기 때문에, iOS 개발자로 살면 언젠가는 사용해야하기 때문에 미리 공부해 보는 것도 좋다고 생각을 합니다.

\ No newline at end of file +

같은 동작을 하는 뷰를 만들어 봤습니다.

차이점이 보이시나요? UIKit(명령형)과 SwiftUI(선언형)을 비교해볼 때

UIKit에서는 Property를 선언 view에 추가하고, Layout에 제약사항을 준 후, action을 할 함수를 만들어서 button에 addTarget 해줍니다.

하지만 SwiftUI에서는 그래로 원하는 위치에 Button을 추가하고 action을 추가하면 끝납니다.

생산성 부분에서 어마어마하게 차이가 난다는 걸 볼 수 있습니다.

UIKit과 SwiftUI를 함께 사용하는 방법

사실 UIView와 SwiftUI를 함께 사용할 수 있는 방법은 다양하게 존재합니다.

SwiftUI는 빠르고 효율적인 앱 개발 환경을 제공할 뿐만 아니라 코드를 크게 변경하지 않아도 다양한 애플 플랫폼에서 동일한 앱을 사용할 수 있게 합니다.

하지만 지도 또는 웹 뷰를 통합해야 하는 특정 기능은 여전히 UIKit을 사용해야 하고, 매우 복잡한 UI 레이아웃을 설계하는 경우에 SwiftUI 레이아웃 컨테이너 뷰 사용이 만족스럽지 않을 수 있습니다.

이런 상황에서는 인터페이스 빌더를 사용을 하는 방식으로 해결할 수도 있습니다.

지금 SwiftUI는 어떨까?

현재까지는 시기상조라는 말도 있고, 회사에서 도입 할 것이라는 말이 있습니다.
이 부분은 사람마다 의견이 다르기 때문에 정확한 대답은 어렵지만, 개인적으로 저는 자신이 처한 상황에서 직접 고려하여 결정하는 것이 좋다고 생각합니다.

SwiftUI 최소 버전은 iOS 기준 13.0이지만, 제대로 사용하려면 15.0 이상이여야 하기 때문에, 이러한 부분은 좀 많이 아쉽긴 합니다.

그리고 현재 SwiftUI는 버그도 있기도 하고, 아직 사용하기에는 불완전하다는 말에 동의는 합니다.
하지만 엄청난 생산성을 갖는다는것, 그리고 Apple이 추구하는 방향성의 UI Framework라는 것은 부정할 수 없기 때문에, iOS 개발자로 살면 언젠가는 사용해야하기 때문에 미리 공부해 보는 것도 좋다고 생각을 합니다.

\ No newline at end of file diff --git a/blog/yackety-yak-ios-4/index.html b/blog/yackety-yak-ios-4/index.html index 60f4f649..8e00ee73 100644 --- a/blog/yackety-yak-ios-4/index.html +++ b/blog/yackety-yak-ios-4/index.html @@ -1,4 +1,4 @@ -와글와글 제4회 발표 회고록

와글와글 제4회 발표 회고록

와글와글 iOS 제 4회 발표 회고

이번 제 4회 와글와글 iOS에서 블로깅하는 방법에 대해서 발표를 했고, 이에 대한 회고 입니다.

발표 준비

발표 전 당시 저는 Publish에 관심도가 높아졌고, 다른 사람들에게 Publish 사용을 권하고 있었을 때
리이오님이 감사하게도 발표를 제안을 주셔서 "Swift로 블로깅하기" 라는 주제로 발표를 하게 되었습니다.

저의 첫 발표였기 때문에, 어떻게 준비해야하나 부터 고민하고, 발표를 어떻게 해야는지 고민을 했던 것 같습니다.

미리 발표 자료를 만들기 위해서 Keynote내에서 어떤 목차로 진행 해야할지 부터 고민을 했습니다.

- 다른 Swift 로 웹을 만드는 라이브러리와 비교
+와글와글 제4회 발표 회고록

와글와글 제4회 발표 회고록

와글와글 iOS 제 4회 발표 회고

이번 제 4회 와글와글 iOS에서 블로깅하는 방법에 대해서 발표를 했고, 이에 대한 회고 입니다.

발표 준비

발표 전 당시 저는 Publish에 관심도가 높아졌고, 다른 사람들에게 Publish 사용을 권하고 있었을 때
리이오님이 감사하게도 발표를 제안을 주셔서 "Swift로 블로깅하기" 라는 주제로 발표를 하게 되었습니다.

저의 첫 발표였기 때문에, 어떻게 준비해야하나 부터 고민하고, 발표를 어떻게 해야는지 고민을 했던 것 같습니다.

미리 발표 자료를 만들기 위해서 Keynote내에서 어떤 목차로 진행 해야할지 부터 고민을 했습니다.

- 다른 Swift 로 웹을 만드는 라이브러리와 비교
 - Publish 에 대한 소개 (소개 & 특징)
 - Publish 설치
 - Publish 시작하기
@@ -10,4 +10,4 @@
 - 장점
 - 느낀점
 - 하고 싶은말
-

이런 목차로 진행하기로 정하고 발표 세부 내용을 작성하였습니다.

이번 발표에서는 "왜 Publish인가?" 라는 것에 대한 저의 의견이 담는 것이 중요했습니다.

또한 잘못된 내용을 전달하면 안되기 때문에, 반복적으로 검토하고 수정하기를 진행하였고, 발표 주제가 마이너한 라이브러리를 소개하기 때문에, Publish에 대한 대략적인 부분에 대한 설명부터 해야하기 때문에, 사람들에게 이해시키는 부분도 필요했고, 어떻게 사용할지에 대한 설명도 필요했습니다.

이런 부분을 생각하다보니 Keynote의 내용이 너무 많아졌고, 발표 주제에 맞는 방향인 간단하게 소개하는 방식으로 바꾸기로 결정하였습니다.

그리고 blog의 대부분 소스를 공개하지 않았기 때문에 너무 레퍼런스가 부족한 상황이였고, 처음 시작하는 사람들이 쉽게 이해할 수 있도록 레퍼런스 마련을 위해서 여러번의 고민 끝에 제가 직접 만든 블로그를 Public으로 공개하기로 결정하였습니다.

발표 당일

대망의 발표날이 찾아왔고, 저녁 7시 부터 발표를 시작할 준비를 하였습니다. 아침에 몇번 다시 내용을 확인하고, 발표에 대비를 하였으나, 점점 긴장을 하게되었습니다. 발표하기 10분 전에 미리 디스코드 방에 들어가서, 미리 대기를 하였습니다.

발표 시작

처음 진행을 할 때 8명으로 시작을 하였고, 추가적으로 3~4명 이상 진행 중에 들어오셨습니다.
발표 진행을 시작하자마자 문제가 발생했습니다.. 😓
첫 발표인 이유도 있었지만, 발표를 많이 해보지 않았기 때문에 너무 긴장해버렸습니다..
제가 너무 긴장해버린 나머지, 목소리도 잘 안나오고, 머리에서는 "아 망했다" 라는 생각이 들어서 추가적으로 더 긴장을 해버렸던 것 같습니다 ㅋㅋ..

정신 없이 발표가 진행되고, 하나의 걱정이 머리를 스쳐갔습니다.

"과연 발표 내용이 잘 전달 되었을까?"

가장 발표에서 중요한 부분이지만, 다른 분들도 Publish를 한번 씩 사용해보겠다 라는 말을 듣고, 그래도 어느정도 발표에서 말하고 싶은 부분은 전달이 됬구나 라고 생각이 되서 다행이라고 생각이 들었습니다.

발표가 끝나고

제가 느끼기에는 아주 긴 발표시간이 지나가고, 개인적으로 긴장해버린 것 때문에 걱정을 많이 했고, 많은 아쉬움이 남았습니다.
그래도 첫 발표를 끝냈다는 생각에 저에게 어떤 부분이 부족하고, 나중의 발표에서 어떤 부분을 주의해야할 지도 알게되는 시간이였습니다.

리이오님이 좋은 자리를 마련해주셔서, 좋은 경험이 됬습니다. (감사합니다.. 🙏)

느낀점

이번에 발표를 해보고, 다른 곳에서도 발표를 해보고 싶다는 생각을 하게 되었습니다.
비록 이번에는 많은 부분이 부족했지만, 내가 알고 있는 것을 다른 사람과 공유하는 것에 대한 재미를 느끼게 되었고, 현재 발표에서 부족한 부분을 해결하기 위해서 더 많은 곳에서 발표하고 싶다는 생각을 하게 되었습니다.

\ No newline at end of file +

이런 목차로 진행하기로 정하고 발표 세부 내용을 작성하였습니다.

이번 발표에서는 "왜 Publish인가?" 라는 것에 대한 저의 의견이 담는 것이 중요했습니다.

또한 잘못된 내용을 전달하면 안되기 때문에, 반복적으로 검토하고 수정하기를 진행하였고, 발표 주제가 마이너한 라이브러리를 소개하기 때문에, Publish에 대한 대략적인 부분에 대한 설명부터 해야하기 때문에, 사람들에게 이해시키는 부분도 필요했고, 어떻게 사용할지에 대한 설명도 필요했습니다.

이런 부분을 생각하다보니 Keynote의 내용이 너무 많아졌고, 발표 주제에 맞는 방향인 간단하게 소개하는 방식으로 바꾸기로 결정하였습니다.

그리고 blog의 대부분 소스를 공개하지 않았기 때문에 너무 레퍼런스가 부족한 상황이였고, 처음 시작하는 사람들이 쉽게 이해할 수 있도록 레퍼런스 마련을 위해서 여러번의 고민 끝에 제가 직접 만든 블로그를 Public으로 공개하기로 결정하였습니다.

발표 당일

대망의 발표날이 찾아왔고, 저녁 7시 부터 발표를 시작할 준비를 하였습니다. 아침에 몇번 다시 내용을 확인하고, 발표에 대비를 하였으나, 점점 긴장을 하게되었습니다. 발표하기 10분 전에 미리 디스코드 방에 들어가서, 미리 대기를 하였습니다.

발표 시작

처음 진행을 할 때 8명으로 시작을 하였고, 추가적으로 3~4명 이상 진행 중에 들어오셨습니다.
발표 진행을 시작하자마자 문제가 발생했습니다.. 😓
첫 발표인 이유도 있었지만, 발표를 많이 해보지 않았기 때문에 너무 긴장해버렸습니다..
제가 너무 긴장해버린 나머지, 목소리도 잘 안나오고, 머리에서는 "아 망했다" 라는 생각이 들어서 추가적으로 더 긴장을 해버렸던 것 같습니다 ㅋㅋ..

정신 없이 발표가 진행되고, 하나의 걱정이 머리를 스쳐갔습니다.

"과연 발표 내용이 잘 전달 되었을까?"

가장 발표에서 중요한 부분이지만, 다른 분들도 Publish를 한번 씩 사용해보겠다 라는 말을 듣고, 그래도 어느정도 발표에서 말하고 싶은 부분은 전달이 됬구나 라고 생각이 되서 다행이라고 생각이 들었습니다.

발표가 끝나고

제가 느끼기에는 아주 긴 발표시간이 지나가고, 개인적으로 긴장해버린 것 때문에 걱정을 많이 했고, 많은 아쉬움이 남았습니다.
그래도 첫 발표를 끝냈다는 생각에 저에게 어떤 부분이 부족하고, 나중의 발표에서 어떤 부분을 주의해야할 지도 알게되는 시간이였습니다.

리이오님이 좋은 자리를 마련해주셔서, 좋은 경험이 됬습니다. (감사합니다.. 🙏)

느낀점

이번에 발표를 해보고, 다른 곳에서도 발표를 해보고 싶다는 생각을 하게 되었습니다.
비록 이번에는 많은 부분이 부족했지만, 내가 알고 있는 것을 다른 사람과 공유하는 것에 대한 재미를 느끼게 되었고, 현재 발표에서 부족한 부분을 해결하기 위해서 더 많은 곳에서 발표하고 싶다는 생각을 하게 되었습니다.

\ No newline at end of file diff --git a/feed.rss b/feed.rss index ae257be0..d7c488dc 100644 --- a/feed.rss +++ b/feed.rss @@ -1,4 +1,4 @@ -jihoon.meThis is a personal blog for iOS Developer jihoonahn.https://blog.jihoon.mekoWed, 29 Nov 2023 13:15:03 +0000Wed, 29 Nov 2023 13:15:03 +0000250https://blog.jihoon.me/blog/publish-part-2Publish 사용하기 part 2Swift publish 커스텀하기https://blog.jihoon.me/blog/publish-part-2Thu, 26 Oct 2023 14:48:00 +0000Publish 구조 작성하기
struct PublishHTMLFactory: HTMLFactory {
+jihoon.meThis is a personal blog for iOS Developer jihoonahn.https://blog.jihoon.mekoWed, 29 Nov 2023 17:07:49 +0000Wed, 29 Nov 2023 17:07:49 +0000250https://blog.jihoon.me/blog/publish-part-2Publish 사용하기 part 2Swift publish 커스텀하기https://blog.jihoon.me/blog/publish-part-2Thu, 26 Oct 2023 14:48:00 +0000Publish 구조 작성하기
struct PublishHTMLFactory: HTMLFactory {
     typealias Site = Example
 
     func makeIndexHTML(for index: Publish.Index, context: Publish.PublishingContext<Example>) throws -> Plot.HTML {
diff --git a/static/icons/copy.svg b/static/icons/copy.svg
new file mode 100644
index 00000000..d875c844
--- /dev/null
+++ b/static/icons/copy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/static/scripts/post.js b/static/scripts/post.js
new file mode 100644
index 00000000..a13b5769
--- /dev/null
+++ b/static/scripts/post.js
@@ -0,0 +1,23 @@
+function attachEvent(selector, event, fn) {
+  const matches = typeof selector === 'string' ? document.querySelectorAll(selector) : selector;
+  if (matches && matches.length) {
+    matches.forEach((elem) => {
+      elem.addEventListener(event, (e) => fn(e, elem), false);
+    });
+  }
+}
+
+window.onload = function() {
+  var host = window.location.host;
+  var pathname = window.location.pathname;
+
+  attachEvent('.copyPost', 'click', function() {
+    var tempInput = document.createElement("input");
+    tempInput.value = host + pathname;
+    document.body.appendChild(tempInput);
+    tempInput.select();
+    tempInput.setSelectionRange(0, 99999);
+    document.execCommand("copy");
+    document.body.removeChild(tempInput);
+  });
+};
diff --git a/styles.css b/styles.css
index 50f66441..cc123d6c 100644
--- a/styles.css
+++ b/styles.css
@@ -622,6 +622,7 @@ pre code .preprocessing {
   margin-right: auto;
   width: 85%;
   overflow: auto;
+  text-align: center;
 }
 
 @media (min-width: 768px) {
@@ -897,6 +898,10 @@ pre code .preprocessing {
   margin: 0.125rem;
 }
 
+.m-1 {
+  margin: 0.25rem;
+}
+
 .mx-0 {
   margin-left: 0px;
   margin-right: 0px;
@@ -952,6 +957,10 @@ pre code .preprocessing {
   margin-bottom: auto;
 }
 
+.mb-0 {
+  margin-bottom: 0px;
+}
+
 .mb-2 {
   margin-bottom: 0.5rem;
 }
@@ -972,6 +981,14 @@ pre code .preprocessing {
   margin-left: 1rem;
 }
 
+.mr-1 {
+  margin-right: 0.25rem;
+}
+
+.mr-1\.5 {
+  margin-right: 0.375rem;
+}
+
 .mt-11 {
   margin-top: 2.75rem;
 }
@@ -988,6 +1005,14 @@ pre code .preprocessing {
   margin-top: 1rem;
 }
 
+.mt-5 {
+  margin-top: 1.25rem;
+}
+
+.mt-6 {
+  margin-top: 1.5rem;
+}
+
 .mt-8 {
   margin-top: 2rem;
 }
@@ -1290,6 +1315,11 @@ pre code .preprocessing {
   border-color: rgb(113 113 122 / var(--tw-border-opacity));
 }
 
+.bg-blog-c-button {
+  --tw-bg-opacity: 1;
+  background-color: rgb(245 245 247 / var(--tw-bg-opacity));
+}
+
 .bg-blog-c-footer {
   --tw-bg-opacity: 1;
   background-color: rgb(245 245 247 / var(--tw-bg-opacity));
@@ -1313,6 +1343,11 @@ pre code .preprocessing {
   background-color: rgb(246 248 250 / var(--tw-bg-opacity));
 }
 
+.bg-neutral-900 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(23 23 23 / var(--tw-bg-opacity));
+}
+
 .bg-white {
   --tw-bg-opacity: 1;
   background-color: rgb(255 255 255 / var(--tw-bg-opacity));
@@ -1331,6 +1366,10 @@ pre code .preprocessing {
   padding: 0.25rem;
 }
 
+.p-1\.5 {
+  padding: 0.375rem;
+}
+
 .p-16 {
   padding: 4rem;
 }
@@ -1356,6 +1395,16 @@ pre code .preprocessing {
   padding-right: 0px;
 }
 
+.px-1 {
+  padding-left: 0.25rem;
+  padding-right: 0.25rem;
+}
+
+.px-1\.5 {
+  padding-left: 0.375rem;
+  padding-right: 0.375rem;
+}
+
 .px-3 {
   padding-left: 0.75rem;
   padding-right: 0.75rem;
@@ -1376,6 +1425,11 @@ pre code .preprocessing {
   padding-bottom: 0px;
 }
 
+.py-2 {
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+}
+
 .py-3 {
   padding-top: 0.75rem;
   padding-bottom: 0.75rem;
@@ -1538,6 +1592,11 @@ pre code .preprocessing {
   color: rgb(68 64 60 / var(--tw-text-opacity));
 }
 
+.text-white {
+  --tw-text-opacity: 1;
+  color: rgb(255 255 255 / var(--tw-text-opacity));
+}
+
 .backdrop-blur-xl {
   --tw-backdrop-blur: blur(24px);
   -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
@@ -1569,6 +1628,21 @@ pre code .preprocessing {
   background-color: rgb(0 0 0 / var(--tw-bg-opacity));
 }
 
+.hover\:bg-gray-300:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(209 213 219 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-zinc-300:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(212 212 216 / var(--tw-bg-opacity));
+}
+
+.hover\:text-black:hover {
+  --tw-text-opacity: 1;
+  color: rgb(0 0 0 / var(--tw-text-opacity));
+}
+
 .hover\:text-white:hover {
   --tw-text-opacity: 1;
   color: rgb(255 255 255 / var(--tw-text-opacity));
diff --git a/tags/index.html b/tags/index.html
index 810cf58f..21ae7211 100644
--- a/tags/index.html
+++ b/tags/index.html
@@ -1 +1 @@
-jihoon.me

Tag

A collection of 15 tags.

\ No newline at end of file +jihoon.me

Tag

A collection of 15 tags.

\ No newline at end of file