시리야 앱 배포해줘

시리 응답이 웰케 애잔하냐...

배경

올해 초 젠킨스 CI 서버 구축을 처음 해봤고, 그걸 계기로 자동화에 관심이 생겨 일 년 동안 틈틈이 팀 내 배포/개발 프로세스를 개선시켜왔다. 사실 관심이 생겼다는 말은 빈약한 표현이고 나는 내가 이 정도로 의미없는 반복 작업을 싫어하는 사람인줄 몰랐다. 아무 생각없이 할 수 있는 반복 작업도 가끔씩하면 정신 건강에 좋다고 생각했었다. 하지만 개발 프로세스에 녹아있던 수작업이 하기 싫어서 어떻게든 자동화할 방법을 찾아서 팀원들을 설득하고 바꿔버렸다. 그리하여 여러 사람의 손을 거쳐야했던 반복적이고 귀찮은 작업을 대부분 자동화했고, 이제는 시리도 우리 앱을 배포할 수 있을 정도로 간단해졌다.

사전 준비

일단은 당연하게도 앱 배포 단계가 자동화되어 있어야 한다. 팀마다 다르겠지만 보통 앱 배포는 최소한 버전업, 빌드, dSYM 처리(크래시 수집 툴에 업로드)를 해야하고 앱스토어용으로 스크린샷 생성하거나 사내 배포용 엔터프라이즈 앱이라면 빌드 결과물을 사내 인프라에 업로드하는 등의 일련의 작업이 있다.

배포 자동화에 큰 도움이 된 것이 fastlane이다. 가독성 좋은 API를 써서 빌드 스크립트를 쉽게 만들 수 있다. 오픈소스 플랫폼이라 여러 사람들이 만든 다양한 플러그인도 있어서 안되는 것이 거의 없다. 특히, xcconfig 파일을 수정할 수도 있고 git 작업도 쉽게 할 수 있고 필요에 따라서는 쉘 스크립트를 추가할 수도 있다. 도입하고 나면 fastlane 명령어 한 줄만으로 배포를 할 수 있게 된다.

그리고 빌드 서버가 필요하다. 요즘은 클라우드 기반 CI 서비스가 많다. 개발자 컨퍼런스를 가봐도 CI 서비스를 하는 스타트업에서 꼭 부스를 운영하고 홍보한다. travis-ci, circleci, bitrise 등이 있지만 이 글에서는 자체 서버를 구축해야하는 무료 CI 인 Jenkins를 기준으로 설명한다.

시리 숏컷 연동

사실 시리를 연동하는 단계는 가장 쉬운 단계이다. CI 서버를 통해 배포를 자동화하는 “사전 준비”에 99%의 시간과 노력이 들어간다. 실제로도 프로세스 자동화는 1년 내내 작업했고 시리 연동은 반나절 밖에 안걸렸다. 가장 이상적으로는 젠킨스 job의 Build Now 버튼만 클릭하면 앱이 배포되는 것이다.

배포 시나리오가 완성되면, 젠킨스 job의 설정에 들어가서 Build Trigger에서 Trigger builds remotely를 체크하고 토큰 값을 지정해준다.

그러면 이제부터 http://JENKINS_URL/job/JOB_NAME/build?token=TOKEN_NAME으로 POST를 날려주기만 하면 배포가 실행된다. 하지만 이대로는 http 통신할 때 젠킨스 서버 authentication을 처리해줘야 하는데 귀찮다면 Build Authorization Token Root 플러그인을 사용하면 위에 지정해준 토큰만으로 접근할 수 있다.

이렇게 젠킨스 플러그인까지 설치해줬다면 아래 명령어를 터미널에 입력하면 배포가 시작된다.

> curl -X POST http://JENKINS_URL/buildByToken/build?job=JOB_NAME&token=TOKEN_NAME

여기까지만 해줘도 배포가 훨씬 덜 귀찮은 작업이 됐다. 하지만 시리 숏컷이 처음 나왔을때부터 시리한테 배포를 시켜보는 것이 로망이었기 때문에 한 단계 더 가봤다. 아이폰에서 시리 숏컷(단축어) 앱을 실행하여 숏컷을 하나 생성한다. 아래처럼 Get Contents of URL 에다가 배포 URL을 넣고 POST를 선택해주고 내가 원하는 명령어를 입력해주면 끝이다.

느낀점

시리 숏컷 연동 자체는 엄청 쉬웠지만 하고나니 일년 동안 꾸준히 개발 프로세스를 자동화하고 개선해온 것에 대한 결실을 맺은 기분이었다. 만약 배포 프로세스가 올해 초의 상태였다면 시리 배포는 너무 멀거나 불가능하게 느껴졌을 것이다. 레츠스위프트 판교 1차 모임에서 전수열 발표자님이 ‘처음부터 의존성이 완벽하게 주입된 코드를 짜야겠다고 생각하지 말고 어제보다 조금이라도 더 나은 상태로 만들면 된다’고 했던 말이 인상 깊었다. 그런데 시리까지 연동하고 나니 그 경험을 조금이나마 해본 것 같다. 자동화하기 좋은 방식으로 프로세스를 바꾸고, 하나씩 조금씩 자동화를 해서 어제보다 조금 덜 귀찮게 만들다보니 여기까지 올 수 있었던 것 같다.

시리 숏컷도 처음 써봤는데 상상 이상으로 잘 만들어져 있어서 놀라웠다. 간단한 인터페이스로 할 수 있는 일이 무궁무진하다. 심지어 if문, 반복문, 변수 할당, 사용자 인풋 받기, 얼럿 띄우기 등등이 가능해서 흡사 앱 개발처럼 느껴진다. 친구한테 알려주니 우스갯소리로 스크래치말고 시리 숏컷으로 프로그래밍 배워야하는거 아니냐고 그랬는데 정말 불가능한 일도 아닌거 같다. 때마침 긱뉴스에서 No Code is New Programming라는 글을 읽게 되었는데, API가 정말 고도화되면 맨 마지막 단계에서는 코드 없는 인터페이스가 탄생한다는 것이고 이게 프로그래밍의 미래 모습이라는 것이다. 시리 숏컷이 이런 개념에 포함되는게 아닌가 싶다. 글이 배포 자동화로 시작해서 시리 숏컷 찬양으로 끝나게 되었는데, 시리 숏컷이 단순히 내 아이폰에 있는 앱을 실행시켜주는게 다가 아니라 여러 API(앱)를 코드 없이 조합할 수 있게 해준다는 것에 큰 영감을 얻게 되었다.

"알겠습니다.."가 너무 애잔하여 응답을 바꿨다.

Tags: siri shortcut, deploy app, siriops  

Siri, deploy an app

Why does Siri's response sound so sad...

Background

I built a Jenkins CI server for the first time early this year, and because of this I became interested in automation, so I’ve been improving my team’s deployment/development process from time to time for a year. Becoming interested is actually a poor expression, and I did not know that I hated meaningless, repetitive tasks this much. I used to think that sometimes doing repetitive tasks that I could do without thinking is good for my mental health. However, I didn’t want to do the manual tasks within the development process, so I somehow found a way to automate it and changed it after persuading my teammates. Therefore, we automated most of the repetitive, cumbersome tasks that had to go through many people, and our app is now so simple that even Siri can deploy it.

Preparations

Obviously, the app deployment stage needs to be automated. It may vary from team to team, but generally, app deployment requires version up, building, and dSYM processing(uploaded to crash collection tool) in the least, and you need to generate screenshots, and if it’s an enterprise app to be deployed within the company, the build should be uploaded to the company infrastructure.

Fastlane was a great help in deployment automation. An API with high readability can be used to easily create a build script. Since it’s an open-source platform, there are various plugins created by several people, so almost nothing is impossible. Especially, xcconfig files can be modified, git tasks can be done easily, and shell scripts also can be added as needed. Once it’s introduced, deployment will be possible with just one line of fastlane command.

And you need a build server. There are many cloud-based CI services. There are always start-ups that provide CI services running a promotion booth at developer conferences. There’s travis-ci, circleci, bitrise, etc. but this article provides information based on Jenkins, a free CI that requires you to build your own server.

Connect Siri Shortcuts

Connecting Siri Shortcuts is actually the easiest step. “Advanced preparations” that automate deployment through the CI server take 99% of the time and effort. We worked on automating processes for a whole year and connecting to Siri took only half a day. Ideally, the app will get deployed by clicking the Build Now button on the Jenkins job.

If you complete the deployment scenario, go to Jenkins job settings and check Trigger builds remotely under Build Trigger, and then assign a token value.

From now on, the deployment is done once the POST is sent as http://JENKINS_URL/job/JOB_NAME/build?token=TOKEN_NAME. This way, you need to process Jenkins server authentications in http communications. But if you think this is troublesome work, you can use the Build Authorization Token Root plugin to approach it only with the assigned token above.

If you’ve installed the Jenkins plugin, the deployment begins once you enter the command below into the terminal.

> curl -X POST http://JENKINS_URL/buildByToken/build?job=JOB_NAME&token=TOKEN_NAME

Even up to here, deployment became a much less cumbersome task. But ever since Siri Shortcuts has been released, it was my dream to make Siri do the deployment so I went a step further. Run the Siri Shortcuts app on your iPhone and create a shortcut. Put the distribution URL in Get Contents of URL, select POST, and enter the desired command, as you see below, and that’s it.

Thoughts

Connecting to Siri Shortcuts was very easy but after I’ve done it, it felt like I got paid off for continuously automating and improving the development process for a year. If the deployment process was like the state it was earlier this year, Siri deployment would have felt too far away or impossible. What presenter Sooyeol Jeon said at the first meeting of Let’s Swift at Pangyo, ‘do not think you have to write a code that’s perfectly injected with dependency from the beginning, but you can make it a little better than yesterday’ left a great impression on me. After connecting Siri, it feels like I’ve gained some experience of what Sooyeol said. I was able to come this far by changing the process so it’s easier to automate, and by automating it one by one, little by little so it’s less troublesome compared to yesterday.

It was also my first time using Siri Shortcut, and it was surprisingly well-made than I imagined it to be. There are so many things you can do with a simple interface. Even if statements, loops, variable allocations, receiving user input, putting up alerts are possible and it feels like developing an app. When I told my friend about it, he jokingly said if I should learn programming using Siri Shortcut instead of Scratch, I don’t think that’s impossible. That time, I read an article, No Code is New Programming on GeekNews, and it was about when APIs have really advanced, there will be an interface without codes at the last step, and that is the future of programming. I thought Siri Shortcuts may be included in this concept. The article started with deployment automation to praise Siri Shortcuts, but I was greatly inspired by the fact that Siri Shortcuts not only runs apps on my iPhone but also allows me to combine multiple APIs(apps) without any code.

"Okay.." sounded so sad so I changed the response.

Tags: siri shortcut, deploy app, siriops  

스위프트의 콤마와 &&의 차이: condition과 expression의 구분

이번 주 인터넷을 돌아다니다가 Swift의 if문에서 ‘,’와 ‘&&’의 차이라는 재밌는 글을 발견했다. 재밌었던 이유는 명료한 답변이 곧바로 떠오르지 않았기 때문이다. 가끔 이렇게 평소에는 별 생각없이 당연하게 쓰던 것에 대한 질문에 말문이 막히는 경우가 있다.

결론부터 한줄 요약 하자면, 콤마는 condition을 이어붙이는 용도로 쓰는 것이고 &&는 두개의 boolean expression을 파라미터로 받는 논리 연산자이다. 라고 결론 내릴 수 있겠다. 따라서 콤마와 &&의 차이는 conditionexpression의 차이를 이해하는데서 시작해야한다.

(1) 위에 “condition을 이어붙인다”고 했는데, 이렇게 이어붙여진 condition들을 condition-list라고 부른다. 스위프트 공식 문서에 따르면 condition-list는,

  • condition 이거나
  • condition , condition-list 이다.

정의에 재귀가 있다는 것만 유의하면 된다. 풀어서 말하면 condition-list는 condition 하나이거나 콤마로 condition을 (정의상 무한정?) 이어붙인 것이다.

  • condition
  • condition, condition
  • condition, condition, condition
  • condition, condition, condition, condition, …

(2) 그러면 condition은 뭘까? 마찬가지로 스위프트 공식 문서에 따르면 condition

  • expression
  • availability-condition
  • case-condition
  • optional-binding-condition

이렇게 네 개 중에 하나를 나타낸다. 아래 세 개는 이름만으로도 뭘 의미하는 꽤 명확해보인다.

(3) 그럼 condition의 한 종류인 expression은 과연 뭘까? expression도 위와 같이 계속 파고 들어갈 수 있지만 주제의 범위를 벗어나기 때문에 이쯤에서 그만하기로 하고, 최대한 간단하게 말해서 ‘연산자를 하나라도 쓴 스위프트 코드 단위’라고 볼 수 있다.

(4) 결국 &&는 하나의 expression을 만들 수 있는 수많은 연산자 중에 하나인 것이고, &&를 쓴 expression은 (condition의 정의에 따라) condition이기도 한 것이다.

그렇다면 원 질문의 예제로 돌아와서, 왜 첫번째는 되고 두번째는 안되는 것일까?

if let a = someOpt, let b = someOtherOpt {  } // works

if let a = someOpt && let b = someOtherOpt {  } // error

첫번째는 optional-binding-condition 두 개를 콤마로 붙인 condition-list 이기 때문에 잘 동작을 한다. 반면에 아래 코드는 && 논리 연산자를 썼는데, 논리 연산자는 두 개의 bool expression을 인자로 받는 연산자이다. 그런데 let a = someOptlet b = someOtherOpt는 bool expression이 아니다. 연산자를 잘못 썼기 때문에 당연히 에러가 난다. 비유하자면 "hello" && "world"가 안되는 것과 같은 이유이다.

또 다른 예제를 보게되면,

if 1 == 1, 2 == 2 {  } //works

if 1 == 1 && 2 == 2 {  } //works

둘다 기능적으로는 동일하게 동작하지만 컴파일러의 눈에는 조금 다르다. 첫번째는 condition(== 연산자를 쓴 expression)이 두 개이고, 두번째는 condition(&& 연산자를 쓴 expression)이 하나인 것이다.

결론으로 돌아오면, 콤마는 condition-list를 만드는 스위프트 문법의 종류이고, &&는 논리 연산자이다. 다시 말해 콤마 앞뒤에는 condition이 와야하고 && 앞뒤에는 boolean expression이 나와야 하는 것이다. 그리고 둘의 차이를 결정 짓는 핵심은 expression은 condition이지만 condition은 expression이 아니다라는 명제이다.

보너스

Q. condition과 condition-list를 굳이 구분해야하나?

A. 그렇다. 왜냐면 condition과 condition-list를 쓸 수 있는 곳이 다르다. while, if, guard 문에는 condition-list를 쓰지만 repeat-while 문에서는 condition만 쓸 수 있다. 콤마로 여러 condition을 이어붙이는 것이 허용된 곳과 아닌 곳이 있는 것이다.

Tags: swift comma, condition-list, AND operator