<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>uuuunseo_.log</title>
        <link>https://velog.io/</link>
        <description>OnO</description>
        <lastBuildDate>Thu, 22 Aug 2024 07:58:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>uuuunseo_.log</title>
            <url>https://velog.velcdn.com/images/uuuunseo_/profile/7baf5414-172c-4dd6-aa50-3eda965eab8e/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. uuuunseo_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/uuuunseo_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[SwiftUI] SwiftUI로 다음 우편번호검색 페이지 구현하기]]></title>
            <link>https://velog.io/@uuuunseo_/SwiftUI-SwiftUI%EB%A1%9C-%EB%8B%A4%EC%9D%8C-%EC%9A%B0%ED%8E%B8%EB%B2%88%ED%98%B8%EA%B2%80%EC%83%89-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@uuuunseo_/SwiftUI-SwiftUI%EB%A1%9C-%EB%8B%A4%EC%9D%8C-%EC%9A%B0%ED%8E%B8%EB%B2%88%ED%98%B8%EA%B2%80%EC%83%89-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 22 Aug 2024 07:58:59 GMT</pubDate>
            <description><![CDATA[<h3 id="구현-범위">구현 범위</h3>
<p>SwiftUI를 사용해서 다음 우편번호 검색 페이지를 구현하려고 합니다.</p>
<p>제가 구현할 범위는 </p>
<ol>
<li>버튼 선택 시 우편번호 검색 Sheet가 올라오도록 구현</li>
<li>우편번호 선택 후 Sheet가 내려가면서 Button에 선택한 주소가 넘어오도록 구현</li>
</ol>
<h3 id="공식문서">공식문서</h3>
<p><a href="https://postcode.map.daum.net/guide">https://postcode.map.daum.net/guide</a></p>
<p>위 링크는 공식문서입니다!</p>
<p>공식문서가 있지만 저는 공식문서대로 진행하면 계속 오류가 발생하더라고요
그래서 다른 분들의 블로그를 보면서 구현해봤습니다.</p>
<h2 id="다음-우편번호검색-페이지-구현">다음 우편번호검색 페이지 구현</h2>
<p>우편번호 서비스 문서를 보면 스크립트나, html로 구현되어있습니다.</p>
<p>구현하는 방식이 클라이언트에 추가하는 방식이 아니라</p>
<h4 id="웹으로-구현-한-뒤-웹뷰로-가여와-클라이언트에서-사용할-수-있는-방식">웹으로 구현 한 뒤 웹뷰로 가여와 클라이언트에서 사용할 수 있는 방식</h4>
<p>으로 구현해야합니다.</p>
<p>그래서 저는 깃페이지를 사용해 우편번호검색 페이지를 만들었습니다! (깃을 사용한 웹사이트가 아니여도 웹사이트 만들듯이 하나 만들면 됩니다!)</p>
<h3 id="깃페이지-만들기">깃페이지 만들기</h3>
<p>일단 퍼블릭 레포를 하나 생성하고</p>
<p>Setting 메뉴 -&gt; 카테고리 Pages를 선택해서 들어가면</p>
<p>Source 창에 브랜치를 선택하는 부분이 있습니다.
거기서
main root save
에 save 버튼을 선택하면 주소가 나옵니다.</p>
<p>그 주소가 바로 저희가 우편번호검색 페이지를 사용할 웹페이지 주소가 됩니다.</p>
<h3 id="우편번호서비스-화면-만들기">우편번호서비스 화면 만들기</h3>
<p>바로 main 브랜치에 add file -&gt; create new file을 선택합니다.</p>
<p>그리고 index.html로 이름을 설정해준 뒤</p>
<pre><code>&lt;html lang=&quot;ko&quot;&gt;
  &lt;head&gt;
    &lt;title&gt;주소 찾기&lt;/title&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,height=device-height,initial-scale=1.0&quot;/&gt;
  &lt;/head&gt;
  &lt;body onload=&quot;execDaumPostcode()&quot;&gt;
  &lt;div id = &quot;layer&quot; style = &quot;display:block; position:absolute; overflow:hidden; z-index:1; -webkit-overflow-scrolling:touch; &quot;&gt;
  &lt;/div&gt;
  &lt;script src=&quot;https://spi.maps.daum.net/imap/map_js_init/postcode.v2.js&quot;&gt;&lt;/script&gt;
  &lt;script&gt;
    window.addEventListener(&quot;message&quot;, onReceivedPostMessage, false);

    function postMessageToiOS(postData) {
        window.webkit.messageHandlers.callBackHandler.postMessage(postData);
    }

    var element_layer = document.getElementById(&#39;layer&#39;);
    function execDaumPostcode() {
      new daum.Postcode({
        oncomplete: function(data) {
          var jibunAddress = &quot;&quot;

          if (data.jibunAddress == &quot;&quot;) {
            jibunAddress = data.autoJibunAddress
          } else if (data.autoJibunAddress == &quot;&quot;) {
            jibunAddress = data.jibunAddress
          }

          var postData = {
              roadAddress : data.roadAddress,
              jibunAddress : jibunAddress,
              zonecode : data.zonecode
          };
          window.postMessageToiOS(postData);
        },
        width : &#39;100%&#39;,
        height : &#39;100%&#39;
      }).embed(element_layer);
      element_layer.style.display = &#39;block&#39;;
      initLayerPosition();
    }

    function initLayerPosition(){
      var width = (window.innerWidth || document.documentElement.clientWidth);
      var height = (window.innerHeight || document.documentElement.clientHeight);
      element_layer.style.width = width + &#39;px&#39;;
      element_layer.style.height = height + &#39;px&#39;;
      element_layer.style.left = (((window.innerWidth || document.documentElement.clientWidth) - width)/2) + &#39;px&#39;;
      element_layer.style.top = (((window.innerHeight || document.documentElement.clientHeight) - height)/2) + &#39;px&#39;;
    }
  &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><p>위 코드를 작성한 뒤에 적용시키고 깃 페이지 주소로 들어가면 </p>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/6de83c98-2b83-48bf-9c8f-ff443b94244e/image.png" alt="">
위 사진처럼 다음 우편번호검색 페이지가 만들어졌어요!!</p>
<h2 id="webkit-사용해서-페이지-구현하기">WebKit 사용해서 페이지 구현하기</h2>
<p>검색페이지를 만들었으니 이제 WebView로 가져와서 사용해야겠죠?</p>
<p>SwiftUI로 사용하려면 UIViewRepresentable을 사용해서 구현해야해요!!</p>
<pre><code>import SwiftUI
import WebKit

struct KakaoPostCodeView: UIViewRepresentable {
    let request: URLRequest
    var webView: WKWebView?
    @Binding var isShowingKakaoWebSheet: Bool
    @Binding var address: String

    init(
        request: URLRequest,
        isShowingKakaoWebSheet: Binding&lt;Bool&gt;,
        address: Binding&lt;String&gt;
    ) {
        self.webView = WKWebView()
        self.request = request
        self._isShowingKakaoWebSheet = isShowingKakaoWebSheet
        self._address = address
        self.webView?.configuration.userContentController.add(KakaoWebController(isShowingkakaoWebSheet: _isShowingKakaoWebSheet, address: _address), name: &quot;callBackHandler&quot;)
    }

    func makeUIView(context: Context) -&gt; WKWebView {
        return webView!
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }

    func makeCoordinator() -&gt; Coordinator {
        Coordinator(parent: self)
    }

    class Coordinator: NSObject, WKNavigationDelegate {
        let parent: KakaoPostCodeView

        init(parent: KakaoPostCodeView) {
            self.parent = parent
        }
    }
}

class KakaoWebController: NSObject, WKScriptMessageHandler {
    @Binding var isShowingKakaoWebSheet: Bool
    @Binding var address: String

    init(
        isShowingkakaoWebSheet: Binding&lt;Bool&gt;,
        address: Binding&lt;String&gt;
    ) {
        self._isShowingKakaoWebSheet = isShowingkakaoWebSheet
        self._address = address
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == &quot;callBackHandler&quot;, let data = message.body as? [String: Any] {
            if message.name == &quot;callBackHandler&quot; {
                print(&quot;message name : \(message.name)&quot;)
                print(&quot;post Message : \(message.body)&quot;)

                if let roadAddress = (data[&quot;roadAddress&quot;]) as? String {
                    print(&quot;roadAddress: \(roadAddress)&quot;)
                    address = roadAddress
                    print(address)
                }
                isShowingKakaoWebSheet.toggle()
            }
        }
    }
}


extension KakaoPostCodeView {
    func callJS(_ args: Any = &quot;&quot;) {
        webView?.evaluateJavaScript(&quot;postMessageToiOS(&#39;\(args)&#39;)&quot;) { result, error in
            if let error {
                print(&quot;Error \(error.localizedDescription)&quot;)
                return
            }

            if result == nil {
                print(&quot;It&#39;s void function&quot;)
                return
            }

            print(&quot;Received Data \(result ?? &quot;&quot;)&quot;)
        }
    }
}</code></pre><p>위 코드가 제가 구현한 코드입니다.</p>
<p>저는 Binding으로 isShowingKakaoWebSheet와 address를 추가했는데요!!
isShowingKakaoWebSheet는 사용자가 검색 후 주소를 선택하면 바로 sheet가 닫히도록 구현하기 위해 추가했고,
address는 사용자가 주소를 선택하면 바로 TextField에 적용 될 수 있게 하려고 추가했습니다.</p>
<p>위 코드들은 다 우편번호 페이지를 불러오기 위한 코드들이이에요!!</p>
<h2 id="사용하기">사용하기</h2>
<pre><code>import SwiftUI

struct ContentView: View {
    @State var isShowingKakaoWebSheet: Bool = false
    @State var address: String = &quot;&quot;
    let webURL: URL? = URL(string: &quot;https://uuuunseo.github.io/DaumWeb/&quot;)

    var body: some View {
        VStack {
            Button {
                isShowingKakaoWebSheet = true
            } label: {
                Text(&quot;주소는 : \(address)&quot;)
            }
        }
        .sheet(isPresented: $isShowingKakaoWebSheet) {
            if let url = webURL {
                KakaoPostCodeView(
                    request: URLRequest(url: url), 
                    isShowingKakaoWebSheet: $isShowingKakaoWebSheet,
                    address: $address
                )
            }
        }
    }
}</code></pre><p>이제 페이지를 구현했으니 원하는 페이지에 sheet를 사용해서 추가만 하면 완성입니다!</p>
<p>KakaoPostCodeView에 보낼 isShowingKakaoWebSheet와 address를 선언하고 깃 페이지 URL을 페이지에 넘겨주기만 하면 완성입니다.</p>
<p>처음에는 이걸 어떻게 구현하지 싶었는데 일단 시작해보고 나니 쉽게 구현할 수 있었던... </p>
<p>코드는 여기서 확인 하실 수 있어요!!!!!</p>
<p><a href="https://github.com/uuuunseo/Studyyy/tree/main/DaumSearchPostCode">https://github.com/uuuunseo/Studyyy/tree/main/DaumSearchPostCode</a></p>
<h3 id="구현-영상">구현 영상</h3>
<img src="https://velog.velcdn.com/images/uuuunseo_/post/2aaa2ce8-fd21-4f2e-adf9-f81f9c44fee7/image.gif" width="50%" height="30%">


<h3 id="참고한-블로그">참고한 블로그</h3>
<p><a href="https://nsios.tistory.com/158">https://nsios.tistory.com/158</a>
<a href="https://da-ye.tistory.com/221">https://da-ye.tistory.com/221</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Swift] Strategy Pattern]]></title>
            <link>https://velog.io/@uuuunseo_/Swift-Strategy-Pattern</link>
            <guid>https://velog.io/@uuuunseo_/Swift-Strategy-Pattern</guid>
            <pubDate>Wed, 29 May 2024 08:06:12 GMT</pubDate>
            <description><![CDATA[<h2 id="전략패턴">전략패턴</h2>
<p>전략 패턴은 여러 알고리즘을 각각 객체로 캡슐화하고, 동일한 목적을 하는 알고리즘들을 하나의 인터페이스로 묶는 알고리즘의 집합을 사용하는 행위패턴입니다.</p>
<p>알고리즘들이 클라이언트 객체에서 교체되면서 사용할 수 있게 됩니다.</p>
<p>따라서, 알고리즘이 클라이언트 객체에 독립적으로 구성되기 때문에 느슨한 연결을 만들 수 있게 되는겁니다.</p>
<p>느슨하게 연결된다는 것은 클라이언트 객체가 알고리즘이 변하게 될 때, 영향을 받지 않는 다는 것을 의미합니다!
만약, A 알고리즘이 수정되어야 한다면, 캡슐화된 해당 알고리즘만 수정하게 되고, 내부적으로 어떻게 수정되고 어떻게 구현되어 있는지 클라이언트 객체는 알지 못합니다.</p>
<br>

<h2 id="구성">구성</h2>
<h3 id="strategy-compositor">Strategy (Compositor)</h3>
<ul>
<li>지원되는 모든 알고리즘에 사용되는 공통적인 인터페이스를 정의합니다.</li>
<li>Context는 Strategy 인터페이스를 사용하여 Concrete Strategy에 정의된 알고리즘을 호출합니다.</li>
</ul>
<h3 id="concrete-strategy">Concrete Strategy</h3>
<ul>
<li>Strategy 인터페이스를 사용하여 알고리즘을 구현합니다.</li>
</ul>
<h3 id="context-composition">Context (Composition)</h3>
<ul>
<li>Concrete Strategy 객체로 구성됩니다.</li>
<li>Strategy 객체에 대한 참조를 유지합니다.</li>
<li>Strategy가 데이터에 접근 할 수 있는 인터페이스를 정의합니다.</li>
</ul>
<br>

<h2 id="언제-사용하나요">언제 사용하나요?</h2>
<ul>
<li>어떤 상황에서 사용할 알고리즘이 여러 개 존재할 수 있을 때 사용합니다. (알고리즘을 런타임에서 교체할 수 있기 때문에 효과적으로 대응 가능)</li>
</ul>
<br>

<h2 id="적용해보기">적용해보기</h2>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/4b5b154f-2524-42e5-82b8-d7e3264390d1/image.png" alt="">
먼저 Strategy 인터페이스 역할을 할 프로토콜을 하나 정의합니다.</p>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/4e9fcb93-96aa-4f71-8947-afa37ff4e92d/image.png" alt="">
그리고 Strategy프로토콜을 채택하는 알고리즘들을 만들어줍니다.</p>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/cef73d0f-8b1b-4fb7-aeba-fa1d08fa216f/image.png" alt="">
그런 뒤에 만든 알고리즘들을 교체해가며 사용할 Context를 구현해줍니다.</p>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/47ba2144-0b11-4af1-b601-7ab7bab64767/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/a857c440-5d38-4cba-952c-77b35a38fced/image.png" alt=""></p>
<p>이렇게 런타임마다 Strategy객체를 변경하면서 알고리즘을 바꿔 사용할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Swift] Decorator Pattern]]></title>
            <link>https://velog.io/@uuuunseo_/Swift-Decorator-Pattern</link>
            <guid>https://velog.io/@uuuunseo_/Swift-Decorator-Pattern</guid>
            <pubDate>Wed, 29 May 2024 05:13:55 GMT</pubDate>
            <description><![CDATA[<h2 id="데코레이터-패턴decorator-pattern">데코레이터 패턴(Decorator Pattern)</h2>
<p>데코레이터 패턴은 메시지를 처리하는 메서드의 동작을 추가해 런타임에 해당 객체의 코드를 수정하지 않고도 새로운 기능을 수행할 수 있게 만들어주는 패턴입니다.</p>
<p>기존 객체를 감싸는 Wrapper를 만들고 해당 Wrapper객체에 다른 기능을 추가해서 Wrapper패턴이라고 불리기도 합니다.</p>
<br>

<h2 id="구성">구성</h2>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/e4ee4c9c-797b-42a3-a990-901b23cf2da4/image.png" alt=""></p>
<h3 id="component">Component</h3>
<ul>
<li>동적으로 추가된 기능을 가질 수 있는 객체에 대한 인스턴스를 정의합니다.</li>
<li>e.g : Wrapper와 Wrapper에 의해 래핑된 객체 모두에 대한 인스턴스를 정의합니다.</li>
</ul>
<h3 id="concrete-component">Concrete Component</h3>
<ul>
<li>Component 인터페이스의 기능들을 추가로 구현한 객체입니다.</li>
<li>새로운 기능들이 추가될 수 있는 객체입니다.</li>
<li>e.g : 래핑되는 객체를 말합니다.</li>
</ul>
<h3 id="decorator">Decorator</h3>
<ul>
<li>Component 인터페이스를 따르는 객체를 참조할 수 있는 필드가 존재합니다.</li>
<li>Component 인터페이스를 따르는 인스턴스를 정의합니다.</li>
</ul>
<h3 id="concrete-decorator">Concrete Decorator</h3>
<ul>
<li>구성 요소에 기능을 추가합니다.</li>
</ul>
<h3 id="client">Client</h3>
<ul>
<li>Component 인터페이스를 통해 모든 객체와 함께 동작하는 여러 계층의 Decorator로 Component를 래핑할 수 있습니다.</li>
</ul>
<br>

<h2 id="언제-사용하나요">언제 사용하나요?</h2>
<ul>
<li>다른 객체들에 영향을 주지않고 개별 객체에 기능을 추가하고 싶을 때 사용합니다.</li>
<li>추가한 기능들은 언제든지 없앨 수 있습니다.</li>
<li>상속을 사용하여 기능을 확장하기 어려울 때 사용합니다. </li>
</ul>
<h2 id="적용해보기">적용해보기</h2>
<h3 id="component-1">Component</h3>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/8d2ea962-8f14-414d-99af-c517b12daf2b/image.png" alt=""></p>
<p>먼저 가장 기본이 될 Component를 추가해줍니다. 예시로 저는 마라탕에 재료를 추가하면 돈이 추가되도록 구현하기 위해 마라탕 protocol을 선언해줬습니다.</p>
<h3 id="concrete-component-1">Concrete Component</h3>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/8f55a21c-a05a-4a19-8661-afbffcf90f5d/image.png" alt=""></p>
<p>그리고 Maratang 프로토콜을 채택하는 기본이 되는 Concrete Component를 만들어 줍니다.
Concrete Component는 재귀를 종료할 base case가 필요하기 때문에 BasicMaratang의 const</p>
<h3 id="decorator-1">Decorator</h3>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/3f6a7664-7a5a-43ec-852d-deb0f179506c/image.png" alt="">
데코레이터 프로토콜을 만들고, 내부에 Maratang타입의 변수를 가지도록 인터페이스를 구성했습니다.
데코레이터 프로토콜은 데코레이터를 적용할 구체적인 객체의 타입을 상속하거나 채택해야하고, 동시에 같은 타입의 인스턴스를 멤버로 가지고 있어야 하기 때문에 이렇게 구성했어요.</p>
<h3 id="concrete-decorator-1">Concrete Decorator</h3>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/be43503c-3d5b-44c9-a4c1-0e1625aeacee/image.png" alt=""></p>
<p>중국당면과 양고기는 생성자로 Maratag타입을 받습니다. 이 타입은 Concrete Component와 Decorator도 가지고 있기 때문에 Decorator를 생성자로 전달하는 것이 가능합니다.</p>
<p>중국당면과 양고기가 구현하는 메서드와 연산 프로퍼티는 생성자로 받은 Maratang 타입이 가진 동명의 메서드/연산 프로퍼티를 호출하고 그 반환 값에 자신의 상태 값을 추가해주는 방식으로 진행됩니다.</p>
<h3 id="사용해보기">사용해보기</h3>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/d71573b5-084f-4a7e-83c4-5dbb6aeb648a/image.png" alt="">
아까 Decorator가 Maratang타입을 따르고 있던 이유가 바로 여러개의 인스턴스를 추가하기 위함이었습니다.
이렇게 인스턴스를 생성해서 출력해보면</p>
<p><img src="https://velog.velcdn.com/images/uuuunseo_/post/8d94e79e-4e45-40e6-b2a6-0cc575901077/image.png" alt="">
저희가 원하는대로 출력됩니다.</p>
<p>이렇게 데코레이터 패턴을 이용해서 OCP를 따르면서 유연하게 변경에 대처할 수 있는 객체를 만들 수 있습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] 중요한 파일을 암호화 해서 GitHub에 올려보자!]]></title>
            <link>https://velog.io/@uuuunseo_/iOS-%EC%A4%91%EC%9A%94%ED%95%9C-%ED%8C%8C%EC%9D%BC%EC%9D%84-%EC%95%94%ED%98%B8%ED%99%94-%ED%95%B4%EC%84%9C-GitHub%EC%97%90-%EC%98%AC%EB%A0%A4%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@uuuunseo_/iOS-%EC%A4%91%EC%9A%94%ED%95%9C-%ED%8C%8C%EC%9D%BC%EC%9D%84-%EC%95%94%ED%98%B8%ED%99%94-%ED%95%B4%EC%84%9C-GitHub%EC%97%90-%EC%98%AC%EB%A0%A4%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Tue, 09 Apr 2024 03:15:30 GMT</pubDate>
            <description><![CDATA[<p>GitHub Actions를 사용해 자동화 스크립트로 빌드를 실행할 때 필요한 파일이지만 GitHub에는 올릴 수 없는 중요한 파일들을 관리하는 방법에 무엇이 있을까요?</p>
<p>바로 gpg파일로 암호화해서 깃허브에 올릴 수 있습니다.
GnuGP 보안 솔루션을 이용해서 오늘은 gpg 파일로 암호화, 복호화하고 CI에 key까지 적용하는 방법을 알아봅시다.
<br></p>
<h3 id="gnugp-설치하기">GnuGP 설치하기</h3>
<p>저는 brew를 사용해서 GnuGP를 설치했습니다.</p>
<pre><code class="language-bash">brew install gnupg2</code></pre>
<p>Gnupg2가 설치 됐다면, 이제 암호화를 시작해봅시다!
<br></p>
<h2 id="암호화-하기">암호화 하기</h2>
<p>암호화를 하는 방법은 간단합니다.</p>
<pre><code class="language-bash">gpg -c {암호화할 파일의 경로}</code></pre>
<p>위 코드를 실행하면,
<img src="https://velog.velcdn.com/images/uuuunseo_/post/07557e94-5756-4989-9edd-d4613272dbe0/image.png" alt="">
터미널에 다음과 같은 화면이 표시됩니다.</p>
<p>이 화면에서 Passphrase, Repeat에 비밀번호를 설정해주고 Enter를 누르면 됩니다.
(추후에 비밀번호를 사용하게 되니, 설정한 비밀번호를 꼭 기록해주세요!)</p>
<p>비밀번호를 설정해주면 바로 암호화가 되면서</p>
<pre><code class="language-bash">File &#39;{암호화 된 파일이름.gpg}&#39; exists. Overwrite? (y/N)</code></pre>
<p>이런 문구가 뜨게 되는데 여기서 y를 입력하면, 
<strong>gpg 파일이 생성되면서 암호화에 성공합니다.</strong>
<br></p>
<hr>
<h4 id="비밀번호를-어떻게-설정해야할지-모르겠다면">비밀번호를 어떻게 설정해야할지 모르겠다면?</h4>
<p>openssl을 사용해보세요.</p>
<pre><code class="language-bash">openssl rand -base64 32</code></pre>
<p>을 터미널에 입력해주면 바로 영어,문자들이 랜덤하게 나열된게 나오게 됩니다.
그걸 비밀번호로 사용해주시면 됩니다.
<br></p>
<hr>
<h2 id="github-actions에서-사용하기">GitHub Actions에서 사용하기</h2>
<h3 id="github-repo에-비밀번호를-secrets으로-저장하기">GitHub Repo에 비밀번호를 Secrets으로 저장하기</h3>
<ol>
<li><p>Settings 페이지로 이동합니다.
<img src="https://velog.velcdn.com/images/uuuunseo_/post/4fb9b9f2-a691-4599-a18a-4a616e980c8a/image.png" alt=""></p>
</li>
<li><p>Settings 페이지 안에 Secrets and variables 옵션에 들어갑니다.
<img src="https://velog.velcdn.com/images/uuuunseo_/post/a47edd38-7200-44a1-aad8-e4c6cfc25a28/image.png" alt=""></p>
</li>
<li><p>Repository secrets에 위에서 설정했던 비밀번호를 <strong>[New repository secret]</strong>버튼을 눌러 저장합니다.
<img src="https://velog.velcdn.com/images/uuuunseo_/post/9164f118-7dfc-4c4f-ab71-b11d17ff794c/image.png" alt=""></p>
</li>
</ol>
<p>위의 순서대로 저장을 해주면
<img src="https://velog.velcdn.com/images/uuuunseo_/post/6341f6c4-14cb-443c-8ff8-b3e88c9287fb/image.png" alt="">
이런 식으로 저장이 됩니다.</p>
<h3 id="스크립트에서-사용하기-예시">스크립트에서 사용하기 (예시)</h3>
<ol>
<li><p>env를 추가합니다.</p>
<pre><code class="language-yml">env:
ENCRYPTED_GPLIST_FILE_PATH: ${{ &#39;.gpg파일 경로&#39; }}
DECRYPTED_GPLIST_FILE_PATH: ${{ &#39;복호화할 파일 경로&#39; }}
GPLIST_PW: ${{ secrets.GOOGLE_SERVICE_ENCRYPTO_PW }}</code></pre>
<br>
</li>
<li><p>gpg파일을 복호화해 저장하는 스크립트를 작성합니다.
```yml</p>
</li>
</ol>
<ul>
<li>name: configure fileName
run: |
  gpg -d -o &quot;$ENCRYPTED_GPLIST_FILE_PATH&quot; --pinentry-mode=loopback --passphrase &quot;GPLIST_PW&quot; &quot;DECRYPTED_GPLIST_FILE_PATH&quot;<pre><code>&lt;br&gt;
</code></pre></li>
</ul>
<p>이렇게 작성하고 브랜치에 Push하면 잘 적용되는 모습을 볼 수 있습니다.</p>
<h4 id="복호화-하는-방법">복호화 하는 방법</h4>
<p>gpg 파일로 암호화 해서 깃허브에 올려서 사용할 때,
클론을 받게 되면 gpg파일만 올라가 있어서 프로젝트 빌드가 진행되지 않을 때 gpg 파일을 복호화하는 방법입니다.</p>
<pre><code class="language-bash">gpg -d -o {복호화한 파일 생성 경로} --pinentry-mode=loopback --passphrase {저장한 비밀번호} {.gpg파일 경로}</code></pre>
<br>
이렇게 GitHub에 중요한 파일을 올릴 때 gpg파일로 암호화해서 올리면 됩니다.

<p>중요한 파일이 있을때 사용해보시면 좋을거 같아요!!</p>
]]></description>
        </item>
    </channel>
</rss>