[SeSAC] August 7, 2023

✔︎ 오늘의 정리

  • API
  • ATS
  • .ipa / .app

 


오늘의 할 일

1. 이름 관련 버그 수정

해결한 방법: 그냥 navigationBarItem에 글자를 없앴다. 더 깔끔해서 오히려 이득 ^_^

 

2. nameLabel inset 넣기

 

class MyPaddingLabel: UILabel {
    var padding: UIEdgeInsets
    
    @IBInspectable
    var left: CGFloat {
        get {
            self.padding.left
        }
        set {
            self.padding.left = newValue
        }
    }
    
    @IBInspectable
    var right: CGFloat {
        get {
            self.padding.right
        }
        set {
            self.padding.right = newValue
        }
    }
    
    @IBInspectable
    var top: CGFloat {
        get {
            self.padding.top
        }
        set {
            self.padding.top = newValue
        }
    }
    
    @IBInspectable
    var bottom: CGFloat {
        get {
            self.padding.bottom
        }
        set {
            self.padding.bottom = newValue
        }
    }

    override init(frame: CGRect) {
        self.padding = .zero
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        self.padding = .zero
        super.init(coder: coder)
    }
    
    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: padding))
    }
    
    convenience init(inset: UIEdgeInsets) {
        self.init(frame: .zero)
        self.padding = inset
    }
    
    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        size.width += padding.left + padding.right
        size.height += padding.top + padding.bottom
        return size
    }
}

아래 블로그를 참조했다.

 

https://als2019.tistory.com/119

 

Padding이 적용되는 Custom UILabel 만들기

개발을 하다보면 Label 영역에 Padding을 주어야 하는 경우가 자주 발생합니다. 그럴때는 UIView를 만들고 SubView로 UILabel을 추가하면서 Leading, Trailing, Top, Bottom space를 Padding할 사이즈만큼 주면 되지만

als2019.tistory.com

 

 

 

3. 이스터에그 넣기...........

 

 

 

 

 

 

 

 

 

 

API(Application Programming Interface)

 

API는 요청이 있어야 응답을 한다.

client가 server에게 정보를 달라고 하는 것을 Request라고 하며, Request는 인증키가 있어야 보낼 수 있다. (간혹 인증키가 없어도 받을 수 있는 게 있긴 함)

Request 요청의 종류는 많지만, 몇 개 꼽아보자면 GET / POST / PUT / PATCH / DELETE가 있는데, 차례대로 살펴보자면 다음과 같다.

  • GET: 리소스 읽어오기
  • POST: 리소스 등록(게시글 작성)
  • PUT: 파일 전송(데이터 대체 / 없으면 생성)
  • PATCH: 리소스 부분 변경(인스타그램 좋아요 같은 경우!)
  • DELETE: 리소스 삭제

 

서버가 client에게 정보를 반환하는 것은 Response라고 하며, JSON / XML 형태로 정보의 값을 전달한다.

XML은 JSON보다 오래된 데이터 표현법으로, html을 닮았다. (갠적으루...)

JSON은 비교적 최근에 나온 데이터 표현법으로, 모바일 앱 개발의 경우에는 JSON이 활용성과 확장성이 좋아 둘 다 있을 경우에는 JSON을 사용하는 것이 좋다.

Swift 4 이전에는 JSON Serialization를 이용하여 정보값을 받았는데, 현재는 Cordable을 자주 사용한다.

 

서버에서 client로 정보를 받아올 때, status code가 같이 넘어온다. 우리는 이 코드를 통해 통신 상태를 알 수 있다.

  • 100번대: 리퀘스트를 받아들여 처리 중(거의 사용 X)
  • 200번대: 리퀘스트 처리 성공!
  • 300번대: 리퀘스트를 완료하기 위하여 추가 동작이 필요
  • 400 / 500번대: 리소스 클라이언트 실패
    • 이때, 400번대의 경우에는 잘못된 요청으로 일어나므로 뭐 잘못한 게 아닌지 살펴봐야 한다... ^_^
    • 500번대의 경우에는 대부분 서버 내부의 문제라고 함!

 

SwiftyJSON과 Alamofire를 이용하여 정보를 받아오는 경우, validate()라는 method를 사용할 수 있는데, 이 method는 본래 성공으로 치지 않는 status code의 경우에도 어느 정도까지는 성공으로 쳐 주자고 미리 정의해 주는 method이다.

 

정상적으로 값을 받아오는 경우, JSON은 아래와 같은 형식으로 나오는데... 

 

https://chrome.google.com/webstore/detail/json-viewer-pro/eifflpmocdbdmepbjaopkkhbfmdgijcc

 

JSON Viewer Pro

A completely free extension to visualise JSON response in awesome Tree and Chart view with great user experience and options. ✅…

chrome.google.com

요 확장프로그램을 이용하면 XML처럼 깔끔하게 볼 수 있다.

 

 

 

 

여기서 만약에 movieNm이라는 변수, 즉 미션임파서블 영화 이름을 가져오고 싶다면 가장 처음의 boxOfficeResult부터 차례대로 타고 들어가서 값을 가져오면 된다. 이후 .stringValue를 빼먹으면 json값으로 나와 사용할 수 없으니 주의할 것 ^_^

 

 

 

 

 

분명!!!! 나중에 까묵을 것 같아서 코드와 함께 정리한 내용을 같이 올려 놓는다.

 

 

        let url = "https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=\(APIKey.boxOfficeKey)&targetDt=20120101"
        AF.request(url, method: .get).validate().responseJSON { response in
            switch response.result {
            case .success(let value):
                let json = JSON(value)
                print("JSON: \(json)")
                
                // movieNM에 접근하려면 차근차근 파싱해야 함(차근차근 자르깅)
                // 위에서부터 차근차근!
                
                
                let name = json["boxOfficeResult"]["dailyBoxOfficeList"][0]["movieNm"].stringValue
                print("==============================")
                print(name) // 미션임파서블:고스트프로토콜
                print("==============================")
            case .failure(let error):
                print(error)
            }

https://www.kobis.or.kr/kobisopenapi/homepg/apiservice/searchServiceInfo.do?serviceId=searchDailyBoxOffice 

 

영화진흥위원회 오픈API

제공서비스 영화관입장권통합전산망이 제공하는 오픈API서비스 모음입니다. 사용 가능한 서비스를 확인하고 서비스별 인터페이스 정보를 조회합니다.

www.kobis.or.kr

 

영화 진흥 위원회의 API를 사용한 것이다.

 

 

특이한 점이 있다면, Request를 보내고 Response를 받는 시간 동안 기다리지 않고 아래 줄이 그대로 실행된다. 

일단 순서대로 실행하지만, 중간에 큰 작업이라면 중간에 다른 스레드에 맡기는 것이다. ^_^

비동기... 적으로 처리하는듯? (아마)

 

 

 

 

 

이어지는 코드는 API를 이용하여 특정 회차의 로또 번호를 가져오는 코드이다.

 

{
	"returnValue":"success",			// 요청결과
	"drwNoDate":"2004-10-30",			// 날짜
	"totSellamnt":56561977000,			// 총상금액
	"firstWinamnt":3315315525,			// 1등 상금액
	"firstPrzwnerCo":4,				// 1등 당첨인원
	"firstAccumamnt":0,
	"drwtNo1":1,					// 로또번호 1
	"drwtNo2":7,					// 로또번호 2
	"drwtNo3":11,					// 로또번호 3
	"drwtNo4":23,					// 로또번호 4
	"drwtNo5":37,					// 로또번호 5
	"drwtNo6":42,					// 로또번호 6
	"bnusNo":6,					// 로또 보너스 번호
	"drwNo":100					// 로또회차
}

이런 식으로 json 데이터를 보내온다. (https://kadosholy.tistory.com/23)

 

 

 

 

    func callRequest(number: Int) {
        // url에  link 넣어주기
        let url = "https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=\(number)"
        AF.request(url, method: .get).validate().responseJSON { response in
            switch response.result {
            // 인터넷이 잘댐
            case .success(let value):
                let json = JSON(value)
                
                let nums: [String] = [
                    json["drwtNo1"].stringValue,
                    json["drwtNo2"].stringValue,
                    json["drwtNo3"].stringValue,
                    json["drwtNo4"].stringValue,
                    json["drwtNo5"].stringValue,
                    json["drwtNo6"].stringValue,
                    json["bnusNo"].stringValue
                ]
                let lotteryNumber = nums.joined(separator: " / ")
                
                self.resultLabel.text = lotteryNumber
                self.numberLabel.text = String(number) + "회 당첨 번호"
                
            // 인터넷이 안댐?
            case .failure(let error):
                print(error)
            }
            
            // => request가 끝날 때까지 기다리지 않음!!
            // 일단 순서대로 실행하지만, 중간에 큰 작업이라면 중간에 다른 스레드에 맡김

        }

데이터를 한번에 배열로 가지고 온 이후에 joined() method를 이용하여 한 문자열로 만들어 해당 Label.text에 넣어 주었당.

 

 

 

 

이렇게 동작한다!

 

 

 

 

 

 

BeerAPI를 이용해서 하나 더 맹글어서 추가한다... ^_^

d이름하여 랜맥추(랜덤맥주추천)

 

 

 

 

 

중간에 안 나오는 게 몇 개 있어서 왜 안 나오지? 하구 찍어보니까 사진이 nil인 게 꽤 있더라 -,-

 

 

 

 

 

 

 

 

 

 

 

 

ATS(App Transport Security)

iOS의 경우, http 주소는 Xcode에서 막혀 있고, https만 받아올 수 있다.

이는 바로 ATS 때문인데, 

 

방법으로는 두 가지가 있는데, 먼저 해당 http 주소를 https로 바꿔보는 것이다.

이 경우에는 해당 주소의 보안서 인증 유무에 따라 해결이 되기도 하고 안 되기도 한다.... 

 

위 방법으로 안 되면 Xcode 내에서 경고를 무시하고 ATS를 비활성화 시킨 뒤에 실행시키는 방법이 있다. 

info.plist에서 이런 식으로 설정해 주면 된다. 

 

아니면 특정 도메인을 제외시킬 수도 있다.

 

 

 

 

 

 

 

.ipa / .app



file -> Project Settings

 

 

 

 

 

 

Data옆 삼각형!!

 

 

Build 폴더에서 해당 파일을 찾아 들어간 뒤에 Product -> Debug-iphonesimulator에 들어가면 있는 어플리케이션 파일이 곧 실행파일이다.

 

 

 

 

 

 

 

 

 

 

'TIL' 카테고리의 다른 글

[SeSAC] August 13, 2023  (0) 2023.08.14
[SeSAC] August 10, 2023  (0) 2023.08.11
[SeSAC] August 6, 2023  (0) 2023.08.07
[SeSAC] August 3, 2023  (2) 2023.08.04
[SeSAC] August 2, 2023  (0) 2023.08.02