2020년 4월 16일 목요일

Objective C로 만들어진 프로젝트에서 swift 사용하기

기존에 Objective C로 구현되어 있는 App 에 신규 기능을 추가 해야 하는데 swift로 하고 싶으면?


1. Xcode Project -> Target -> Build Settings -> Defines Modules 'Yes'
   Xcode Project -> Target -> Build Settings -> Swift Language Version 5







2. Swift Code 추가

3. Objective C 에서 swift 함수를 사용할 경우 @objc func , 프로퍼티를 참조 할 경우 @objc var

4. Swift에서 기존 Objective C 모듈에 연동이 필요한 경우
   프로젝트이름-Bridging-Header.h 에 #import 추가

이 과정을 거치고 나면 objective c / swift를 함께 이용할 수 있다.
ojbective c 에서 swift 로 만든 ViewController를 이용하고 swift로 만든 ViewController에서 기존 objective c 모듈에 기능을 이용 할 수 있다.




2019년 10월 3일 목요일

Xcode 11 storyboard 앱에서 swiftUI 함께 쓰기

iOS 개발에 많은 변화 들이 있었다.

xib에서 storyboard
Objective C에서 swift
그리고 swift 버젼업들

storyboard에 auto resize 에서 auto layout

그리고 또 swift 버젼업

계속해서 바뀌고 바뀌고 나름대로 즐겁게 따라 갔다.

그런데 swiftUI 이번에 한번더 완전 새로와 지는듯 하다.

Xcode 11이 릴리즈 되어 맛볼수 있으나
macOS를 카탈리나로 업그레이 하지 않아 미리보기 창이 되지 않는다.

Xcode 11로 새프로젝트를 만들면 디폴트가 swiftUI다

언젠가는 늘 그렇듯이 대세가 될것이다.

하지만 지금은 마음의 준비가 되지 않았고 익숙한 스토리보드를 좀더 쓸듯 하다.

그래서 스토리보드 기반 프로젝트에 간단한 UI만 swiftUI를 쓰고 싶은 생각이 들어
이래저래 리서치를 하고 아래와 같은 방법으로 간단하게 이용할 수 있음을 알게 되었다.



1. 프로젝트 시작은 storyboard

2. 디폴트로 생성된 ViewController에 ContainerView를 추가

3. ContainerView와 연결된 ViewController를 삭제

4. 스토리보드에 HostingViewController를 추가

5. ContainerView와 HostingViewController를 Embed Segue로 연결






6. New 메뉴로 swiftUI 를 하나 추가
기본적으로 hello world 코드가 되어 있는 SwiftUI 파일 그대로 이용한다.

7. 스토리보드에 EmbedSegue를 ViewController 코드로 연결 한다.


@IBSegueAction func addSwiftUIView(_ coder: NSCoder) -> UIViewController? {
        return UIHostingController(coder: coder, rootView: SwiftUIView())

    }

자이제 run을 해보면 시작 ViewController에 ContainerView가 SwiftUI로 동작 한다.

요방법으로 당분간 짬뽕해서 쓰다가
swiftUI가 되세가 되면 익숙해 지겠지...

실행화면과 프로젝트 구성된 파일들은 다음과 같다.

2019년 5월 4일 토요일

Xcode Server 를 이용한 CI (Continuous Integration)

Xcode Sever 를 이용한 CI (Continuous Integration)


Xcode로 개발 하면서 bitbucket에 있는 repository에 프로젝트를 자동으로 내려 받아 빌드 하고 테스트 하는 CI를 설정 하고 사용 하는 방법을 기록으로 남겨 본다.

Xcode 서버 활성


Xcode 서버를 활성 시키려면
Xcode -> Preference -> Server & Bots















스위치를 켜기만 하면 끝이다.

이제 Account로 가서 Xcode Server를 추가 한다.




Bot 설정


이제 비트 버킷으로 관리 되는 프로젝트를 클론 하여 Xcode로  열어 본다.

cocoapod 을 이용하여 xcworkspace로 열려진 프로젝트의 경우
.xcworkspace는 git으로 관리 하지 않는 상황에서 Xcode Server가 스스로 pod install 및 .xcworkspace를 로드 하여 프로젝트를 빌드 하고 테스트 하는 방법을 기술 한다.

bitbucket으로 클론 하면 xcworkspace가 존재 하지 않는다.
.xcworkspace는 git으로 add 하지 않고 관리 하지 않기 때문이다.

# pod install을 수행한다.
# open projectname.xcworkspace 로 워크스페이스를 연다.

워크스페이스로 열고 Xcode bot을 설정 하는 이유는 단지 bitbucket 의 url을 자동으로 열기 위함이었다.

상관 없다.

Product->Create Bot 으로 봇을 생성 한다.













워크스페이스를 연 이유는 자동으로 bitbucket  설정 을 위해서 였다.







CI 스케줄을 정한다. 매시간 이 디폴트이다.




테스트를 하는 시뮬레이터 및 디바이스를 선택 하는 단계 모든 디바이스와 모든 시뮬레이터를 설정 할 경우 Xcode Server가 빌드하고 테스트 하는동안 수많은 시뮬레이터 와 CPU 점유을 맥머신에 이륙 소리를 만날 것이다. 특정된 모델만 선택 하는 것을 강추 한다.







인증 서 단계등을 완료 하고 나면 봇이 생성 된다.

봇이 완료되면 바로 integration을 수행하는데 100% 실패 한다.

이유는 cocoa pod 프로젝트 그리고 .xcworkspace를 bitbucket에 pull 하지 않았기 때문에 빌드 과정에서 에러가 발생 한다.  projectname.xcworkspace 파일이 없기 때문에 실패 하는 것이다.




상단에 Edit bot을 클릭 한다.
맨 오른쪽 Trigger를 선택 한다.
하단 + 버튼을 클릭 하여

pre-integration script를 생성 한다.

#!/bin/sh
cd "${XCS_PRIMARY_REPO_DIR}/projectname"
pwd
/usr/local/bin/pod install

위와 같은 스크립트를 생성한다.

Xcode Server bot 이 프로젝트를 클론 해온다음
스크립트가 pod install을 수행하여 모든 pod 라이브러리를 내려 받아 놓고
생성된 .xcworkspace를 로드하여 빌드 및 테스트를 진행 한다.

unit test, ui test를 프로젝트에 등록 해두었으면 자동으로 빌드 및 테스트 까지 수행 하여 Xcode bot이 리포팅 해준다.

2019년 2월 9일 토요일

macOS 에서 eclipse jee 와 CDT 동시에 설치 및 아이콘 변경 하기

요즘 회사에서 web 이나 서버 API 를 간간히 배우면 개발을 해야하기 때문에 spring을 이용하기 위해 vscode 부터 eclipse 까지 이것 저것 만저 보았다.

스프링 개발을 위해 eclipse jee를 설치 하고 잘 사용 하고 있는 상황 그런데 raspberry pi에 C 로 개발해야 할 일이 생겨서 eclipse CDT도 설치 해봐야 하는 상황이 발생 했다.


기존 설치되어 있는 eclipse jee에  CDT 플러그인을 install software 메뉴로 추가로 설치를 하면 하나의 이클립스가 java / c++ 모두 되는 IDE가 되는 것으로 보인다.

하지만 자바 프로젝트 워크 스페이스가 열리면서 무언가 화면은 C++ IDE 였다가, java IDE 였다가 하는 것이 맘에 안든다.

해서 eclipse jee 가 설치된 mac 머신에 새로 eclipse cdt를 설치 하기로 했다.

eclipse/cpp-2018-12 ,  jee-2018-12 로 나뉘어 설치 되게 된다.

하지만 아이콘이 같은 모양이라서 어떤게 java IDE인지 어떤게 c++ IDE인지 구분이 가지 않는다.



https://github.com/eclipse-cdt/cdt/blob/master/debug/org.eclipse.cdt.debug.application/icons/cc.icns
여기에서 C++ eclipse icns를 다운 받는다.

cc.icns 를 Eclipse.icns로 이름을 변경 하고

eclipse CDT 설치 경로에서 패키지 보기로 하여  Resource 디렉토리에 있는
Eclipse.icns에 복사하여 아이콘을 바꾼다.

어떤이유에서인지는 모르지만 실행전에는 dock에 아이콘이 변경 되지 않지만 실행중에는
변경되어 어떤것이 java인지 C++인지 구분이 된다.

이정도면 만족 한다.







2019년 1월 15일 화요일

visual studio code 로 spring maven project를 할때 너무 package does not exist로 밑줄이 많을떄

https://github.com/redhat-developer/vscode-java/issues/161

java linter 플러그인을 제거 해야 한다.

springframework.beans.factory.anotation 등등
멀쩡한 코드들이 빨간줄이 가는 문제가 있었다.

https://github.com/redhat-developer/vscode-java/issues/161의 답변중에 하나인
java linter 플러그인이 문제 인 듯 하다.

2019년 1월 12일 토요일

visual studio code로 java spring maven project 하기

java spring 은 eclipse로 작업하는게 일반적이다.

spring을 시작하는 입장에서 eclipse의 불편함이 개발에 어려움에 한 몫 하고 있다.

현업에서 가장 많이 사용 하는게 eclipse이니 사실 장점이 더 많을 수 있지만
eclipse는 느리고 macOS에서 다크 테마도 부자연 스럽고 맘에 들지 않는다.

하여 code 편집기로 자주 사용하는 vscode를 spring 개발에 이용하려 함이다.

이미 eclipse로 만들어진 spring maven 프로젝트 폴더를 vscode로 열어서 빌드및 tomcat debug가 가능 하도록 하는것이 목표이다.

MacOS 기준에서 테스트 하였다.


1. tomcat 설치 mac os
eclipse 개발 환경으로도 tomcat 설치는 필요하다.


http://igeniusdo.tistory.com/12
톰캣 버젼을 다운로드 받아서 /usr/local 폴더에  복사한다.
/Library/Tomcat 으로 심볼릭 링크를 걸어준다.

2. maven 설치
아파치 maven을 다운 받아서 /usr/local 에 복사한다.
https://maven.apache.org/install.html

cat .bash_profile 
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home

export PATH=/usr/local/apache-maven-3.6.0/bin:$PATH

위와 같이 JAVA홈과 maven PATH를 설정 한다.


3.vscode에 java 관련 플러그인 설치
https://code.visualstudio.com/docs/languages/java

여기에 언급한 플러그인을 몽땅 설치 한다.

이상태에서 eclipse spring maven project 폴더를 폴더 열기를 하면 다음과 비슷한 화면으로 로딩 된다

.


4.톰캣 서버 추가

TOMCAT SEVERS에서 +를 누른다음 /Library/Tomcat 폴더를 선택하여 tomcat 을 추가한다.
tomcat의 마우스 오른쪽 버튼을 눌러 Open Server Configuration을 선택 하여 server.xml을 편집 할 수 있다.  port 설정등을 할 수 있다.

5. 프로젝트 maven 빌드
MAVEN PROJECTS 에서 마우스 오른쪽 버튼으로 package를 선택 한다.

정상적으로 빌드가 끝나면 target 디렉토리에 .war 파일이 생성 된다.

6. tomcat 디버깅


디버깅도 잘 된다.




2018년 12월 14일 금요일

XCTest 에서 비동기 통신 class를 테스트를 하려면?

https://developer.apple.com/documentation/xctest/asynchronous_tests_and_expectations/testing_asynchronous_operations_with_expectations


위 링크를 보면 좋은 예제가 있다.


만일 네트워크 RESTFul API를 요청 하는 함수들 과
응답에 결과를 delegate로 호출 해주는 방법으로 만든 클래스가 있다면

이 class의 unit 테스트를 만들려면 testcase 함수 에서는 응답이 오기전에 XCAssertEqual()등의 메서드를 호출 할 수 없다. 네트워크 응답을 delegate로 받고 테스트가 진행 되어야 한다.


XCTest case 함수에서
XCTestExpectation 변수를 전역 변수로 만들고

테스트 케이스 함수에서 네트워크 요청 후
wait(for: [expectation], timeout: 10.0)
위와 같은 코드로 대기를 하게 한다.

XCAssertEqual() 메서드든 wait 코드 아래에 위치 하게 한다.

네트워크 클래스의 delegate 응답 결과를 처리 하는 protocol 메서드에서
expectation.fulfill() 을 호출 하여 대기를 풀어 준다.

그럼 wait이 풀리고 XCAssertEqual에서 테스트 판단이 이루어진다.

말로 설명한 TestCase 코드는 다음과 같다.

let expectation = XCTestExpectation(description: "Network API TEST")
    func testLogin() {
        // 1. given

        // 2. when
        network.login = Network.Login(aId: "choijh", aPassword: "1234567a")
        network.request(API: Network.API.Login, delegate: self)

        wait(for: [expectation], timeout: 10.0)

        // 3. then
        XCTAssertEqual( self.success, true, "Login success")
    }
    
    func testLoginFail() {
        // 1. given
        
        // 2. when
        network.login = Network.Login(aId: "choijh", aPassword: "a")
        network.request(API: Network.API.Login, delegate: self)
        
        wait(for: [expectation], timeout: 10.0)
        
        // 3. then
        XCTAssertEqual( self.success, false, "Login fail wrong password")

    }
    
    func onReceiveSuccessFail(_ success: Bool, api: Network.API) {
        self.success = success
        expectation.fulfill()

    }

2018년 10월 7일 일요일

Xcode에서 이미지 없이 둥근 버튼, 원 버튼 디자인 적용 하기

1. 다음과 같은 라운드 버튼을 이미지 없이





zeplin 오른쪽 사이드에 사각형 이라 표시되고 전혀 image asset에 대한 정보가 없다.
디자이너는 그냥 파란색 도형을 디자인 한것이다.

로그인 버튼은 사각형이며 파란색 도형인데 이미지가 없다?

이러한 경우는

UIVew를 상속 받은 UIButton에서 conerRadius를 설정 하여 처리 하면 된다.
결국 코딩으로 해야 한다.


2. 이번에는 속이 투명한 완전 원형 버튼






width / height 값이 동일하게 그리고 conerRadius를 width/2 로 설정 하면 원이 된다.
결국 코딩이다.

viewDidLoad에 코딩으로 하지 않고 스토리보드 인터페이스 빌더에서 속성으로 처리 하고 싶다면?


import UIKit

extension UIView {
    
    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }
    
    @IBInspectable var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }
    
    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(cgColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.cgColor
        }
    }

}


위와 같이 extension을 작성 하면

@IBInspectable 덕에 IB에 표시된다.



extension은 @IBDesignable이 적용이 되지 않아 storyboard 랜더링은 그대로 사각형이지만 런타임에서는 훌륭한 타원으로 표출 된다.


2번 원 버튼의 경우 배경색을 투명으로 하고 border with  와 border color 를 적용 하고 corner radius를 width에 1/2로 적용 하면 원 버튼이 표현 가능 하다.





















Xcode storyboard 리팩토링

Main.storyboard에 ViewController를 계속해서 디자인 하다 보면
성능이 별로 좋지 않은 mac에서는 랜더링 속도가 현저하게 떨어진다.

ViewController에 image등을 올리는 작업이 늘어 나면 늘어 날 수록 더이상 편집 자체가
너무 느려 하기 어려워 질 수도 있다.


이렇게 하나의 Main.storyboard에 모든 ViewController를 때려 박지 않고
여러개의 storyboard 파일로 나누어 segue를 연결 할 수 있다.


스토리보드 리팩토링 방법

1. 새로운 스토리 보드 파일을 추가 한다.
2. 기존 Main.storyboard 파일과 새로 만든 스토리 보드 파일을 보기 좋게 그룹으로 생성 하여 추가 한다.
3. Main.storyboard 파일에서 일부 연결된 ViewController들을 선택 하여 Cmd + X로 자른다.
4. 새로 추가된 스토리 보드 파일에 붙여 넣기를 한다.
5. 새로 추가된 스토리 보드에 첫번째 ViewController를 is Initial View Controller로 체크 한다.
6. Main.storyboard 파일에서 새로 추가된 스토리 보드와 segue를 연결 한다.





Main.storyboard를 간단하게 바꾸고 segue에 연결은 스토리 보드 레퍼런스로 한다.


Xcode 10에서는 라이브러리 화면이 팝업으로 나오게 되어 있다. Cmd + Shift + L




두번째 항목이 스토리 보드 레퍼런스 이다.

이런한 과정을 통해 프로젝트 성격에 맡도록 storyboard 파일을 나누면
각각의 스토리 보드에서 적은수의 View Controller를 처리 하도록 하여 Xcode에서 보다 쾌적 하게 작업 할 수 있다.

2018년 9월 20일 목요일

iOS ViewController 그라데이션 배경색 적용 하기


위와 같이 zeplin에서 색상 정보가 표시되고 ViewController의 배경색을 적용 해야 하는 경우

디자이너님에게 배경 PNG를 주세요! 라고 할 수도 있고
코드로 해결 할 수도 있다.

위 두점은 그라데이션의 시작점이다.
그리고 두개의 색상 정보가 있다.

extension CAGradientLayer {
    
    convenience init(frame: CGRect, colors: [UIColor]) {
        self.init()
        self.frame = frame
        self.colors = []
        for color in colors {
            self.colors?.append(color.cgColor)
        }
        startPoint = CGPoint(x: 0, y: 0)
        endPoint = CGPoint(x: 1, y: 1)
    }
    
    convenience init(frame: CGRect, colors: [UIColor], startPoint: CGPoint, endPoint: CGPoint) {
        self.init()
        self.frame = frame
        self.colors = []
        for color in colors {
            self.colors?.append(color.cgColor)
        }
        self.startPoint = startPoint
        self.endPoint = endPoint
    }
    
    func createGradientImage() -> UIImage? {
        
        var image: UIImage? = nil
        UIGraphicsBeginImageContext(bounds.size)
        if let context = UIGraphicsGetCurrentContext() {
            render(in: context)
            image = UIGraphicsGetImageFromCurrentImageContext()
        }
        UIGraphicsEndImageContext()
        return image
    }

}

위코드에서 첫번째 convenience 초기화는 대각선 즉 0,0 ~ 1,1 로 그라데이션 을 적용 하는 것이고
추가로 두번째 convenience초기화는 startPoint와 endPoint를 파라메터로 전달 할 수 있도록 만든 초기화 이다.


위와 같이 extension을 만들고

실제 ViewController에서 imageView를 전체 영역으로 올리고 다음과 같이 코딩을 한다.

    @IBOutlet weak var backgroundImage: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        
        var colors = [UIColor]()
        colors.append( colorLiteral(red: 0, green: 0.6941176471, blue: 1, alpha: 1))
        colors.append( colorLiteral(red: 0.05882352941, green: 0.8392156863, blue: 0.8078431373, alpha: 1))
        let gradientLayer = CAGradientLayer(frame: self.view.frame, colors: colors, startPoint: CGPoint(x: 0.5, y:0), endPoint: CGPoint(x:0.5, y:1))
        backgroundImage.image = gradientLayer.createGradientImage()


    }


colorLiteral을 사용해서 숫자로 표시되지만 실제로른 Xcode에서 색상 표를 이용해 hex로 입력 한것이다.


CGPoint(x: 0.5, y:0)  ~ CGPoint(x:0.5, y:1) 은 중앙 상단에서 중앙 하단을 의미 한다.













2018년 8월 17일 금요일

네비게이션 컨트롤의 rootViewController 변경하기

 앱 최초 실행시에 intro -> 가입유도 / 또는 로그인

로그인 성공이후는 main 으로 실행 되는 앱이 있다고 하면

어느 경우는 intro가 navigation controller의 rootViewController 이고

어느 경우는 main이 navigation controller의 rootViewCotnorller  가 된다.

main으로 계속 실행되던 앱에서 logout 기능을 이용하면 login viewController가

navigationViewController에 rootViewController가 되어 실행된다.


스토리 보드를 이용하고 segue를 잘 쓰려고 하는데 앱 최초 진입점이 다르고
navigation controller를 결국에는 storyboard Embed in 으로 해서 만들 수 도 없고

결국 코드로 ViewController를 storyboard에서 찾아다가 push 하고 navigation controller를 초기 화 하고 복잡하게 ... 스파게티...


이러한 앱을 개발 할때 다음과 같이 하면 좀 수월 하다.

1. navigation controller 는 storyboard에 만들지 않는다.

2. navigation controller에 root가 될 viewController 들 ( 2개 또는 3개) 는
attribute inspector에서 top bar 항목을 설정 해준다.

그래야 하위 segue가 연결된 viewController들이 네비바가 있는것처럼 디자인 할 수 있다.

3. init viewController 및 navgation controller의 rootController를 appdelegate.swift에서 구현 한다.



didFinishLaunchingWithOptions 메서드에서 UserDefaults 등으로 구현하여 현재 상황에 맡는 ViewController를 rootViewController로 하여 navigation Controller를 설정 하고 시작 한다.

//intro
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let root = storyboard.instantiateViewController(withIdentifier: "IntroViewController")
        nvc = UINavigationController(rootViewController: root)


        window?.rootViewController = nvc

        window?.makeKeyAndVisible()


로그인 등이 완료되어 main으로 시작 하거나, 또는 로그 아웃으로 인해 다시 intro로 시작 해야 하는 경우를 대비해 
스위칭 하는 메서드를 appdelegate에 구현 한다.
func switchIntro() {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewController(withIdentifier: "IntroViewController")
        nvc = UINavigationController(rootViewController: vc)
        
        self.window?.rootViewController = nvc
        window?.makeKeyAndVisible()
    }
    
    func switchMain() {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewController(withIdentifier: "MainViewController")
        nvc = UINavigationController(rootViewController: vc)
        
        self.window?.rootViewController = nvc
        window?.makeKeyAndVisible()

    }



어떠한 ViewController에서 navigaion Controller의 루트를 변경 하고자 하면 다음과 같이 하면 된다.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
            
            appDelegate.switchIntro()




2018년 6월 6일 수요일

iPhone 6 7 8 plus 에서 상태바가 크게 나오는 앱 올바른 스케일로 나오게 하려면?

실제로 오래전에 만들어진 프로젝트에서 코드를 추가하다 보니

플러스 모델에서 화면 스케일이 업 되어 표출 되는 경우를 발견 했다.

실제로 아직도 내가 사용하는 iphone 6+ 에서 사용되는 앱중에 이렇게 오래된 프로그램인 듯 보이는 앱들이 존재 한다.

내가 사용중인 앱중에는  증권통,  키움증권 영웅문  과 같은 앱들이 아직도 상태바가 크게 보인다. 마치 오래전에 만든 앱이 6+에서 그냥 화면이 늘어 나서 보이는 느낌이다.

대신 증권 앱이나 기업 은행 앱은 최근에 바로 잡힌 듯 하다.



위에부터 키움증권, 증권통, facebook 의 iPhone 6 +에서 스크린샷이다.

왜 이러한 현상이 나타날까?

실제로 오래전에 만들어진 앱에 코드를 추가하고 유지보수 하다가 이러한 현상을 바로 잡기 위해 프로젝트 설정을 해메고 찾고 하였지만 해답은 의외로 간단 했다.



Launch Screen 스토리 보드르 추가 하여 위와 같이 프로젝트를 설정하면
올바른 크기로 프로그램이 실행 된다.

다음은 스택오버플로우의 관련 글이다.
https://stackoverflow.com/questions/25754942/how-to-enable-native-resolution-for-apps-on-iphone-6-and-6-plus

알면 별것 아니고 모르면 개고생이다.

증권통앱에 이방법을 알려주고 싶다.

2018년 4월 18일 수요일

Xcode 9 에서 컬러 리터럴 사용하기

코드에서 색상 값을 UIColor()에 생성자에 RGB 값으로 코딩을 하면 무슨 색인지 코드만 보고는 알수가 없다.



Xcode에서는 이러한 점을 고려하여 위와 같이 color literal을 지원하게 되었다.
색상이 Xcode에디터에서 문자 처럼 표시 된다.

color lteral을 코드에 적용 하는 방법은 다음과 같다.

color literal을 타이핑 하면 다음과 같이 코드 완성이 이루어지려 한다.


에디터에서 색상을 더블클릭 하면 색상 선택 창이 나타난다.




Other를 선택 하여 RGB 및 alpha 값을 적용 하여 원하는 색상 리터럴 문자를 만들수 있다.




이렇게 코드를 작성하면 실제는 colorLiteral() 로 코딩되어 있고 Xcode editor 상에서는 색상으로 표시되어 가독성이 좋다.