Let's Encrypt Expiry Bot 메일 조치

 네이버 클라우드에 우분투 서버를 하나 운영하고 있다. 여기에 가비아에서 도메인을 하나 사서 연결시켰음 API 서비스를 위해 https 필요해서 LetsEncrypt 설정하여 Haproxy로 부하분산을 설정했다. 처음에 잘 설정되었다고 생각했는데 인증서 갱신이 되지 않았나보다. 찾아보니 설명이 부실하여 나름 다시 적용하고 정리한다. 1. 80 과 443 포트가 열려 있는지 확인하고 열려 있으면 닫는다. $ netstat -an | grep ':80' $ netstat -an | grep ':443' 만약 열려 있다면 닫는 방법은 haproxy 를 중지하면 된다. $ sudo systemctl stop haproxy 2. standalone 으로 인증서를 발급한다. $ sudo certbot certonly --standalone -d www.example.com 인증서가 발급되면 /etc/letsencrypt/live/www.example.com/ 폴더에 파일이 생성된다. 3. haproxy 에서 사용할 인증서로 생성한다. $ DOMAIN='www.example.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/$DOMAIN.pem' 4. 이제 haproxy 를 다시 기동한다. $ sudo systemctl start haproxy 

Realm Studio 사용할 때 시뮬레이터 연결 안될때

이미지
 Realm 디비를 오랫만에 다시 사용하게 되었다. 시뮬레이터로 디비의 내용을 확인하면서 개발을 해야 하는데 Realm Studio 프로그램으로 이를 연결하고자 하는데  사용자 폴더에서 라이브러리가 보이지 않는다. 1. 파인더를 연다. 2. 왼쪽 사인더 바에서 사용자를 선택한다. 3. 상단 설정 클릭한다. 4. 새로운 창에서 제일 밑의 라이브러리 폴더 보기를 체크한다.

서버용 스위프트에서 MongoDB 와 Perfect 사용해서 Collection 수가 replyInt 로 나와서 처리가 힘들때

서버용 스위프트로 모듈을 만들때이다. 보통 API 를 만들때 사용한다. 데이터베이스는 MongoDB를 사용했다. 웹서버 모듈은 Perfect 를 사용했고 디비연결은 PerfectMongoDB를 사용했다. 문제는 컬렉션의 수를 셀때이다. 결과 값이 replyInt(500) 이런식으로 나온다. 이를 Int 로 변경해야 처리가 편한데....., 검색해보니 나오지 않는다. 어쩐다...., let countResult = collection.count(query: bson) if case .replyInt(let count) = countResult {   // 여기서 count 가 Int 이므로 처리하면 된다.   print("count \(count)") } 이 방법을 사용하면 카운트의 수를 가져올 수 있다. 처음에 이게 안되어서 find 결과를 세었는데  수가 많아지면 너무 오래 걸려서  결국은 count 를 사용할 수 밖에 없다.

swift pickerView toolbar > uiconstraintbasedlayoutdebugging 오류 추적

일단 화면에 PickerView 가 있다. 그리고 그 위에 ToolBar 를 추가하여 확인 버튼을 달았다. 하지만 실행하면 uiconstraintbasedlayoutdebugging 오류가 생성되었음. let toolbar = UIToolbar () toolbar. barStyle = . default toolbar. isTranslucent = true toolbar. tintColor = . black toolbar. sizeToFit () let flexBarButton = UIBarButtonItem (barButtonSystemItem: . flexibleSpace , target: nil , action: nil ) let doneBarButton = UIBarButtonItem (title: "확인" , style: . plain , target: self , action: #selector ( endEditing )) toolbar. items = [flexBarButton, doneBarButton] toolbar. isUserInteractionEnabled = true          birthYearTextField . inputAccessoryView = toolbar cityTextField . inputAccessoryView = toolbar 일단 소스는 위와 같이 추가하였음. 검색을 해보니 툴바와 피커뷰를 같이 생성하라고 하는 등등.... 모두 안되었다. 아래와 같이 하니까 오류 없이 잘 된다. let toolbar = UIToolbar (frame: CGRect (x: 0 , y: 0 , width: UIScreen . main . bounds . width , height: 37 )) 즉, 툴바를 생성할 때 크기를 지정해주면 된다.

whose view is not in the window hierarchy

swift 5로 코드를 작성 중이었다. self.performSegue(withIdentifier: "ResultToMainSegue", sender: nil) 이 코드가 실행 되면서 나는 오류이다. 그냥 버튼에 이벤트로 적용하면 잘 되는데... 구글 애드몹을 적용하여 광고를 시청하고 끝나는 시점에 넣으니 오류가 난다. whose view is not in the window hierarchy 검색해보니 대충 이게 첫번째 뷰가 아니어서 그런다 첫번째 뷰를 찾아서 거기서 명령을 실행해야 한다고 한다. 그렇게 해보았다. 역시 되지 않는다. 내가 해결한 방법은 이것이다. DispatchQueue.main.async {   self.performSefue(withIdentifier: "ResultToMainSegue", sender: nil) } 이렇게 하니 잘된다. 현재 뷰에서 광고뷰로 넘어가고 다시 현재 뷰로 넘어오면서 뷰의 계층 구조가 명확히 정립되지 않은 상태에서 메인창을 호출하니 오류가 날때도 있고 아닐때도 있었을꺼 같다. 항상 기초에 충실해야겠다.

MySQL Multiple rows 를 one query 구현하기

MySQL 에 자료를 갱신할 일이 생겼다. 갱신할 자료를 가져와 배열에 담았다. list = [adm, bay, car, del, ear] 이를 반복하면서 Update 를 했더니 오래 걸린다. 자료가 약 300 ~ 400 개인데 3~4초가 나온다. 검색을 해보니 INSERT INTO tb_temp (a, b, c) VALUES(1, 2, 3) ON DUPLICATE KEY UPDATE c = c + 1 이걸 이용하면 된다고 한다. 뭐 반복문 돌면서 sql 하나의 문자열로 만들었다. 디비 결과는 중복 입력이었다. 다시 검색을 해보니 비교로 사용하는 첫번째 항목은 무조건 Primary 이어야 한다고 한다. 디비의 구조를 변경하였다. 다시 실행해보니 중복 없이 잘 갱신된다. 실행속도도 400개 정도가 1초 이내로 나온다.

swift Kuery mysql Error shim.h & mysql.h 대응 방법

리눅스에서 스위프트로 작성한 앱에서 MySQL 접속할 일이 생겼다. Swift-Kuery & SwiftKueryMySQL 을 추가하면 된다고 하여 추가하였다. Package.swift 파일에 두개의 모듈을 추가하고 $ swift package update 를 한 다음 혹시나 하여 컴파일을 해 본 다음에 진행하자 $ swift build 결과가 에러를 토해 내였다. <module-includes>:1:10: note: in file included from <module-inclues>:1: #include "shim.h> ~~~~ # error: 'mysql.h' file not found 대충 이런식이다. 해결 방법은 mysqlclient 관련 모듈이 없어서 나는 오류이다 $ sudo apt-get install libmysqlclient-dev 설치 한 후 컴파일 하니 오류가 나지 않는다.