<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>hello world</title>
    <link>https://www.artfrige.com/</link>
    <description>베이스 연주는 건강에 좋습니다</description>
    <language>ko</language>
    <pubDate>Mon, 27 Apr 2026 22:56:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>artfrige</managingEditor>
    <image>
      <title>hello world</title>
      <url>https://t1.daumcdn.net/cfile/tistory/275FCC4956EB41752F</url>
      <link>https://www.artfrige.com</link>
    </image>
    <item>
      <title>까먹지 않으려고 쓰는 Combine framework 기본사항</title>
      <link>https://www.artfrige.com/418</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. Publisher&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Publisher 는 값을 발행하는 발행자를 말함. 구독자는 Publisher 가 방출하는 값을 전달받을 수 있음.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1717771260539&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Foundation
import Combine

//publisher
let publisher = [0,1,2,3,4,5].publisher

//subscriber가 구독자가 방출하는 값을 받아 그 중 짝수만을 프린트함
let subscriber = publisher
    .filter {
        $0 % 2 == 0
    }
    .sink { intValue in
        print(&quot;\(intValue)&quot;)
    }&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. Cancellable&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;구독을 취소할 수 있는 타입. 컴바인에서 퍼블리셔를 구독하게 되면 Cancellable(혹은 AnyCancellable) 을 반환하며 .cancel() 메서드를 이용하여 언제든 구독을 취소할 수 있음.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1717771572488&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Foundation
import Combine

//매 1초마다 현재 시간을 방출하는 컴바인 타이머
let timer = Timer.publish(every: 1, on: .current, in: .default).autoconnect()

//구독자가 매 초마다 타이머의 값을 프린트함
let timerSubscriber: AnyCancellable = timer.sink { time in
    print(time)
}

//5초 후 구독을 종료함
Task {
    DispatchQueue.global(qos:.default).asyncAfter(deadline: .now() + 5) {
        timerSubscriber.cancel()
        print(&quot;Subscription is cancelled.&quot;)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. PassthroughSubject&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;PassthroughSubject의 특징은 아래와 같음.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 초기값을 가지지 않음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. 구독자는 구독한 이후 변경되는 값부터 받아볼 수 있음&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1717772198937&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Foundation
import Combine

//PassthroughSubject Publisher로 첫번째 제네릭은 전달할 타입, 두번째는 에러 타입.
let publisher = PassthroughSubject&amp;lt;Int, Never&amp;gt;()

//첫번째 구독자
let subscriber1: AnyCancellable = publisher.sink { integer in
    print(&quot;integer1 is: \(integer)&quot;)
}

publisher.send(123) //구독자1이 123을 출력

//두번째 구독자
let subscriber2 = publisher.sink { integer in
    print(&quot;integer2 is: \(integer)&quot;)
}

publisher.send(456) //두 구독자 모두 456을 출력
publisher.send(789) //두 구독자 모두 789를 출력

/*
 위의 순서에 따른 프린트 결과:
 integer1 is: 123
 integer1 is: 456
 integer2 is: 456
 integer1 is: 789
 integer2 is: 789
*/&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4. &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;CurrentValueSubject&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;CurrentValueSubject의 특징은 아래와 같음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 초기값을 가짐&lt;br /&gt;2. 구독자는 구독과 동시에 즉시 값을 전달받을 수 있음&lt;br /&gt;3. 새로운 값을 방출할 때마다 구독자에게 자동으로 알림&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1717772791567&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Foundation
import Combine

//PassthroughSubject Publisher로 첫번째 제네릭은 전달할 타입, 두번째는 에러 타입.
let publisher = CurrentValueSubject&amp;lt;Int, Never&amp;gt;(100) //100은 initial value

//첫번째 구독자
let subscriber1: AnyCancellable = publisher.sink { integer in
    print(&quot;integer1 is: \(integer)&quot;) //초기값 100은 이곳에서 한번만 프린트됨
}

publisher.send(200) //갱신된 값 200을 구독자1이 프린트함

//두번째 구독자
let subscriber2 = publisher.sink { integer in
    print(&quot;integer2 is: \(integer)&quot;) //구독자 2가 새로 설정된 초기값 200을 프린트함
}

publisher.send(300) //구독자 1,2가 모두 갱신된 값 300을 프린트함

/*
 위의 순서에 따른 프린트 결과:
 integer1 is: 100
 integer1 is: 200
 integer2 is: 200
 integer1 is: 300
 integer2 is: 300
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이렇게 써놔야 까먹어도 또 볼수있겠지...&lt;/span&gt;&lt;/p&gt;</description>
      <category>programming</category>
      <category>combine</category>
      <category>ios</category>
      <category>rxswift</category>
      <category>swift</category>
      <category>SwiftUI</category>
      <category>uikit</category>
      <category>스위프트</category>
      <category>애플</category>
      <category>프로그래밍</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/418</guid>
      <comments>https://www.artfrige.com/418#entry418comment</comments>
      <pubDate>Sat, 8 Jun 2024 00:10:29 +0900</pubDate>
    </item>
    <item>
      <title>UIKit + Combine을 기초로 한 타이머 예제</title>
      <link>https://www.artfrige.com/417</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;할말은 주석에 다 써놨다.&lt;/p&gt;
&lt;pre id=&quot;code_1708140155203&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// import Combine 까먹지 말것
import UIKit
import Combine

// UIKit에서는 ObservableObject 프로토콜을 채택 안해도 동작함.
// SwiftUI에서는 @StateObject 로 ViewModel 을 선언해야 하기 때문에 꼭 필요함.
// 예제에서는 그냥 멋있어 보이려고 채택함
class TimerClass: ObservableObject {
    
    // 프로퍼티에 @Published 프로퍼티 래퍼를 달아주면 값을 발행(publish) 할 수 있게 됨
    @Published var count: Int = 0
    var timer: Timer = Timer()
    
    init() {
        initTimer()
    }
    
    func initTimer() {
        //1초에 한번 publish 하는 값을 +1씩 갱신
        self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [weak self] _ in
            guard let self = self else { return }
            self.count += 1
        })
    }
    
    func stopTimer() {
        self.timer.invalidate()
    }
}

class CombineTimerExampleViewController: UIViewController {
    
    let timerViewModel: TimerClass = TimerClass()
    let timerCount: UILabel = UILabel()
    let stopButton: UIButton = UIButton()
    
    //구독자의 타입인 Cancellable이 담길 곳
    var cancellable: AnyCancellable?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //뷰 셋업
        setupView()
        
        //뷰 바인딩
        bind()
    }
    
    private func bind() -&amp;gt; () {
        // 뷰에 갱신될 값은 구독 함수인 sink() 를 통해서 구독됨.
        // sink()가 방출하는 값은 AnyCancellable 타입이고, 이걸 위해 만들어둔 self.cancellable에 담고
        // sink()클로저에 어느 뷰와 묶어줄지만 선언해주면 알아서 값이 바뀔 때마다 뷰가 갱신됨.
        // 주의해야 할 점은 뷰 갱신을 위해 @Published 프로퍼티를 받아올 때에는 $수정자를 붙여야 함 (.count 가 아니고 .$count)
        self.cancellable = timerViewModel.$count.sink { [weak self] count in
            guard let self = self else { return }
            self.timerCount.text = &quot;\(count)&quot;
        }
    }
    
    private func setupView() -&amp;gt; () {
        timerCount.textAlignment = .center
        timerCount.font = UIFont.systemFont(ofSize: 30)
        timerCount.translatesAutoresizingMaskIntoConstraints = false
        
        stopButton.configuration = .borderedProminent()
        stopButton.configuration?.title = &quot;Stop Timer&quot;
        stopButton.addTarget(self, action: #selector(stopTimer), for: .touchUpInside)
        stopButton.translatesAutoresizingMaskIntoConstraints = false
        
        self.view.backgroundColor = UIColor.systemBackground
        self.view.addSubview(timerCount)
        self.view.addSubview(stopButton)
        
        NSLayoutConstraint.activate([
            timerCount.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            timerCount.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
            timerCount.widthAnchor.constraint(equalTo: self.view.widthAnchor, constant: -40),
            timerCount.heightAnchor.constraint(equalToConstant: 40),
            
            stopButton.topAnchor.constraint(equalTo: timerCount.bottomAnchor, constant: 20),
            stopButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
        ])
    }
    
    @objc func stopTimer() {
        //타이머 멈추기
        timerViewModel.stopTimer()
    }
    
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>programming</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/417</guid>
      <comments>https://www.artfrige.com/417#entry417comment</comments>
      <pubDate>Sat, 17 Feb 2024 12:23:50 +0900</pubDate>
    </item>
    <item>
      <title>XCode 에서 swiftpm 경로가 없다는 에러가 날 경우.</title>
      <link>https://www.artfrige.com/416</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;엑스코드에서 프로젝트 이름을 바꾸며 내부 디렉토리의 디렉토리 이름까지 전부 바꾸는 바람에 dependency 경로에 문제가 생겨서 프로젝트를 수동으로 옮길 뻔 했는데..&lt;br /&gt;다행히 구글의 한 용자 덕분에 나의 시간과 노력을 아낌.&lt;/p&gt;
&lt;pre id=&quot;code_1708004751535&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;~/Library/Developer/Xcode/DerivedData/&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;문제가 있는 Dependency를 삭제한 후 엑스코드를 종료함&lt;/li&gt;
&lt;li&gt;파인더에서 위의 경로로 이동한 다음 DerivedData 디렉토리 안의 문제가 있는 Dependency에 관련된 디렉토리를 지움&lt;br /&gt;(혹시 모르면 다 지우던가..)&lt;/li&gt;
&lt;li&gt;XCode 를 실행하고 다시 Dependency를 설치.&lt;/li&gt;
&lt;li&gt;PROFIT!&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이래도 안되면? 나도몰루...&lt;/p&gt;</description>
      <category>programming</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/416</guid>
      <comments>https://www.artfrige.com/416#entry416comment</comments>
      <pubDate>Thu, 15 Feb 2024 22:49:10 +0900</pubDate>
    </item>
    <item>
      <title>안까먹으려고 쓰는 ㅈ바스크립트 async/await 간단정리</title>
      <link>https://www.artfrige.com/415</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ㅈ바스크립트에서 await 은 Promise 를 방출하는 놈에 달아줄 수 있다&lt;/p&gt;
&lt;pre id=&quot;code_1697861286887&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async function printData(){
    let endpoint = &quot;https://jsonplaceholder.typicode.com/posts/1&quot;
    let dataset = await fetch(endpoint).then((res) =&amp;gt; { return res.json() })

    try {
        console.log(dataset)
    } catch(e) {
        console.log(e)
    }
}

printData() //쨘 json 데이터 프린트 성공&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에서 fetch 가 Promise 를 방출하기 때문에 await 키워드를 달아서 파싱된 json을 dataset 에 담아 줌.&lt;br /&gt;그렇기 때문에 try 문에서 받아온 json 데이터를 .then()으로 Promise 해결하지 않고도 사용 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;async/await 을 쓰는 이유야 여러개 있겠지만, 그 중 최고의 이유는 .then() 체인조차도 마지막엔 콜백지랄을 해야되기 때문에 어떻게든 불편할 수밖에 없었던 우리의 마음을 달래기 위한 최고의 솔루션이기 때문이지 않나 싶고...&lt;/p&gt;</description>
      <category>programming</category>
      <category>async</category>
      <category>await</category>
      <category>JavaScript</category>
      <category>promise</category>
      <category>자바스크립트</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/415</guid>
      <comments>https://www.artfrige.com/415#entry415comment</comments>
      <pubDate>Sat, 21 Oct 2023 13:16:36 +0900</pubDate>
    </item>
    <item>
      <title>Codeigniter3 프레임워크에 .env 환경설정 파일 적용하기</title>
      <link>https://www.artfrige.com/414</link>
      <description>&lt;pre id=&quot;code_1697862020394&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$composer require vlucas/phpdotenv&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;을 프로젝트 루트 디렉토리에서 실행하면 의존성에 phpdotenv가 주입됨&lt;br /&gt;그다음 index.php에서 아래 코드를 최상단에 추가함&lt;/p&gt;
&lt;pre id=&quot;code_1697862064617&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;require 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv-&amp;gt;load();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 프로젝트 root디렉토리에 .env 파일을 생성하고 아래와 같이 불러 쓰면됨&lt;/p&gt;
&lt;pre id=&quot;code_1697862072581&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$someEnvVariable = $_ENV[&quot;YOUR_ENV_VARIABLENAME&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;composer 가 설치되지 않았거나 설치하지 않은 채로 적용하고 싶다면 아래 github repository를 참조할 것.&lt;br /&gt;&lt;a title=&quot;PHPDotenv for CodeIgniter (Installation without Composer)&quot; href=&quot;https://github.com/agungjk/phpdotenv-for-codeigniter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/agungjk/phpdotenv-for-codeigniter&lt;/a&gt;&lt;/p&gt;</description>
      <category>programming</category>
      <category>.env</category>
      <category>codeigniter3</category>
      <category>php</category>
      <category>프레임워크</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/414</guid>
      <comments>https://www.artfrige.com/414#entry414comment</comments>
      <pubDate>Wed, 30 Aug 2023 10:20:03 +0900</pubDate>
    </item>
    <item>
      <title>[SwiftUI] NavigationLink(_ titleKey, _isActive, desitination)이 Deprecated 라구요?</title>
      <link>https://www.artfrige.com/413</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;아 걱정하지 마십시오!&lt;br /&gt;그런 당신을 위해 준비한&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;.navigationDestination(isPresented: Binding&amp;lt;Bool&amp;gt;, destination: () -&amp;gt; View)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 있으니까요..&lt;br /&gt;(그리고 당연히 위 메서드는 NavigationStack 안의 View객체 밑에 달아줘야 함..)&lt;/p&gt;</description>
      <category>ios</category>
      <category>navigation</category>
      <category>SwiftUI</category>
      <category>내비게이션</category>
      <category>앱</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/413</guid>
      <comments>https://www.artfrige.com/413#entry413comment</comments>
      <pubDate>Tue, 15 Aug 2023 00:05:52 +0900</pubDate>
    </item>
    <item>
      <title>Baldur's Gate III</title>
      <link>https://www.artfrige.com/412</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.18.png&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vvQZg/btsq8KRLmtL/KYJK9Ilv44EmcWh2VQAJGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vvQZg/btsq8KRLmtL/KYJK9Ilv44EmcWh2VQAJGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vvQZg/btsq8KRLmtL/KYJK9Ilv44EmcWh2VQAJGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvvQZg%2Fbtsq8KRLmtL%2FKYJK9Ilv44EmcWh2VQAJGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1268&quot; height=&quot;224&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.18.png&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.20.png&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t7WwF/btsrh0FHptT/fj9OtaeDYw1C2Cgj2NFGZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t7WwF/btsrh0FHptT/fj9OtaeDYw1C2Cgj2NFGZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t7WwF/btsrh0FHptT/fj9OtaeDYw1C2Cgj2NFGZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft7WwF%2Fbtsrh0FHptT%2Ffj9OtaeDYw1C2Cgj2NFGZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;178&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.20.png&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.23.png&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uljms/btsrjr4avzC/OV9PYwv67GiPTwLPUEukb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uljms/btsrjr4avzC/OV9PYwv67GiPTwLPUEukb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uljms/btsrjr4avzC/OV9PYwv67GiPTwLPUEukb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuljms%2Fbtsrjr4avzC%2FOV9PYwv67GiPTwLPUEukb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;128&quot; height=&quot;80&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.23.png&quot; data-origin-width=&quot;128&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.25.png&quot; data-origin-width=&quot;74&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVPGcN/btsrauOPDeF/viqqylGeLlKF8Yjn9W7L11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVPGcN/btsrauOPDeF/viqqylGeLlKF8Yjn9W7L11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVPGcN/btsrauOPDeF/viqqylGeLlKF8Yjn9W7L11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVPGcN%2FbtsrauOPDeF%2FviqqylGeLlKF8Yjn9W7L11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;74&quot; height=&quot;66&quot; data-filename=&quot;스크린샷 2023-08-14 오후 11.58.25.png&quot; data-origin-width=&quot;74&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 이걸 어떻게 참냐고 ㅋㅋㅋㅋㅋ&lt;br /&gt;&lt;s&gt;세일 언제하냐?&lt;/s&gt;&lt;/p&gt;</description>
      <category>hobby</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/412</guid>
      <comments>https://www.artfrige.com/412#entry412comment</comments>
      <pubDate>Mon, 14 Aug 2023 23:59:52 +0900</pubDate>
    </item>
    <item>
      <title>[Swift] Property Wrapper 변수명의 Prefix</title>
      <link>https://www.artfrige.com/411</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;가령 아래와 같은 코드가 있다고 친다면,&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;@Binding var momentDate: Date&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 변수에는 세 가지 방법으로 접근할 수 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;self._momentDate&lt;/li&gt;
&lt;li&gt;self.momentDate&lt;/li&gt;
&lt;li&gt;self.$momentDate&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번은 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Binding&amp;lt;Date&amp;gt;&lt;/span&gt; 구조체 자체를 나타낸다.&lt;br /&gt;2번은 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;self._momentDate.wrappedValue&lt;/span&gt;를 타나낸다. 즉 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Date&lt;/span&gt; 자료형의 값 그 자체이다. View Body의 UI를 렌더링 할 때에는 이 값을 사용한다.&lt;br /&gt;3번은 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;self._momentDate.projectedValued&lt;/span&gt;와 같다. 다시 말해 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Binding&amp;lt;Date&amp;gt;&lt;/span&gt;이며, 이 값은 Child View에게 내려주면 Child View의 UI가 값을 변경할 때 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Binding의 경우 Projected Value($)는 self 이다. 그리고 _와 $의 차이는 액세스 레벨 뿐이다. 하지만 프로퍼티 래퍼마다 각자 다른 형식의 값을 나타낼 수 있다. (예를 들어 &lt;a href=&quot;https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties/#Projecting-a-Value-From-a-Property-Wrapper&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Language Guide&lt;/a&gt; 의 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;@SmallNumber&lt;/span&gt;를 살펴보자)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문: &lt;a href=&quot;https://stackoverflow.com/a/65209375&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;StackOverflow&lt;/a&gt;&lt;/p&gt;</description>
      <category>programming</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/411</guid>
      <comments>https://www.artfrige.com/411#entry411comment</comments>
      <pubDate>Sun, 13 Aug 2023 12:06:24 +0900</pubDate>
    </item>
    <item>
      <title>github 원격 저장소 계정 정보 저장</title>
      <link>https://www.artfrige.com/410</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;git config --global user.name 'YOUR_GITHUB_ACCOUNT'&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;git config --global user.password 'YOUR_GITHUB_ACCOUNT_TOKEN'&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;github account token은 아래의 경로에서 발급받을 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-13 오후 10.55.16.png&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;934&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/15DoH/btrWeGD5ey3/2NByDmTNHNju7SjuiR4IB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/15DoH/btrWeGD5ey3/2NByDmTNHNju7SjuiR4IB1/img.png&quot; data-alt=&quot;1. 계정 &amp;amp;gt; Settings&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/15DoH/btrWeGD5ey3/2NByDmTNHNju7SjuiR4IB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F15DoH%2FbtrWeGD5ey3%2F2NByDmTNHNju7SjuiR4IB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;934&quot; data-filename=&quot;스크린샷 2023-01-13 오후 10.55.16.png&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;934&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1. 계정 &amp;gt; Settings&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-13 오후 10.55.37.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOQD9e/btrWbiFdsCl/XdiIQIHbirwps5Z5YebgPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOQD9e/btrWbiFdsCl/XdiIQIHbirwps5Z5YebgPk/img.png&quot; data-alt=&quot;2. 좌측 사이드바 메뉴에 Developer Settings&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOQD9e/btrWbiFdsCl/XdiIQIHbirwps5Z5YebgPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOQD9e%2FbtrWbiFdsCl%2FXdiIQIHbirwps5Z5YebgPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;676&quot; height=&quot;228&quot; data-filename=&quot;스크린샷 2023-01-13 오후 10.55.37.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2. 좌측 사이드바 메뉴에 Developer Settings&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-13 오후 10.55.57.png&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sm4OO/btrWdnygGay/4PkflWxWyb59EWvpd1YVOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sm4OO/btrWdnygGay/4PkflWxWyb59EWvpd1YVOK/img.png&quot; data-alt=&quot;Tokens 에서 발급받은 내용을 입력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sm4OO/btrWdnygGay/4PkflWxWyb59EWvpd1YVOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsm4OO%2FbtrWdnygGay%2F4PkflWxWyb59EWvpd1YVOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;222&quot; data-filename=&quot;스크린샷 2023-01-13 오후 10.55.57.png&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Tokens 에서 발급받은 내용을 입력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>programming</category>
      <category>Git</category>
      <category>계정</category>
      <category>관리</category>
      <category>원격저장소</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/410</guid>
      <comments>https://www.artfrige.com/410#entry410comment</comments>
      <pubDate>Fri, 13 Jan 2023 22:59:15 +0900</pubDate>
    </item>
    <item>
      <title>git 원격 저장소 force push</title>
      <link>https://www.artfrige.com/409</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;nbsp;! [rejected]&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; main -&amp;gt; main (fetch first)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 에러가 나오고 push 가 안될때 강제로 해결하는 법.&lt;br /&gt;주의할 점은 아래 방법을 수행할 시 &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;리모트에 있는 모든 커밋이 증발&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;하므로&lt;i&gt; &lt;/i&gt;여러 사람이 함께 작업하는 공동 프로젝트에는 사용하지 말 것.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;git push -u origin +REMOTE_REPO_BRANCH&lt;br /&gt;&lt;br /&gt;예) git push -u origin +main&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 명령을 실행하면 리모트 브랜치에 강제로 push 해서 덮어 써 버리게 된다.&lt;/p&gt;</description>
      <category>programming</category>
      <category>fetch</category>
      <category>first</category>
      <category>Git</category>
      <category>오류</category>
      <category>해결</category>
      <author>artfrige</author>
      <guid isPermaLink="true">https://www.artfrige.com/409</guid>
      <comments>https://www.artfrige.com/409#entry409comment</comments>
      <pubDate>Fri, 13 Jan 2023 22:51:53 +0900</pubDate>
    </item>
  </channel>
</rss>