3월, 2020의 게시물 표시

[iOS] 간단한 키체인과 해싱으로 보안 강화 (Basic iOS Security: Keychain and Hashing)

이미지
[iOS] 간단한 키체인과 해싱으로 보안 강화 (Basic iOS Security: Keychain and Hashing) 민감한 데이터를 저장하고, 저장된 데이터를 안전하게 꺼내어 사용자 인증 하는 과정을 Keychain을 이용하여 구현하는 방법을 소개합니다. 해당 포스트의 원문은 다음과 같습니다 : https://www.raywenderlich.com/129-basic-ios-security-keychain-and-hashing 소스코드 다운로드 AuthViewController.signInButtonPressed() 로그인 버튼이 눌렸을 떄 호출 AuthViewController.signIn() 함수 호출 AuthViewController.signIn() 사용자의 입력 종료 이메일, 비밀번호 입력 받은 데이터 검증 디바이스의 이름 가져오기 이름, 이메일, 비밀번호로 User 데이터 만들기 AuthController.signIn() 로그인 함수 호출 AuthController.signIn() class func passwordHash(from email: String, password: String) -> String { let salt = "x4vV8bGgqqmQwgCoyXFQj+(o.nUNQhVP7ND" return "\(password).\(email).\(salt)".sha256() } 입력받은 이메일과 비밀번호를 넘겨줘 AuthController.passwordHash()로 해싱 키체인(Keychain)에서 앱의 데이터를 식별하는데 사용되는 서비스 이름을 상단에 정의 KeychainPasswordItem.savePassword()로 암호 키체인에 저장 UserDefaults에 현재 유저정보 저장 KeychainPasswordItem(service: serviceName, account: user.email).s

[swift] 구조체(struct)와 클래스(class)의 비교

이미지
[swift] 구조체(struct)와 클래스(class) 구조체와 클래스는 코드블럭을 만들 때 쓰이고 그 문법 또한 매우 닮았다. 하지만 다른점이 있기 때문에 그 특성을 잘 파악하고, 필요한 부분에서 활용할 수 있도록 정리한다. 정의 방법 (Definition) 구조체는 struct , 클래스는 class 라는 키워드를 사용하여 정의한다. struct Student{ // properties and methods } class Student { // properties and methods } 프로퍼티와 메소드 (Properties and Methods) 이 예제에서는 학생의 구조체와 클래스의 정의 예제이다. SomeStudent struct 와 AnotherStudent class 모두 firstName, lastName, grade라는 properties를 가지고 grade를 출력해주는 printGrade() 메소드를 가진다. 다른 점은 클래스에서는 init() 함수를 따로 정의 해줘야 한다. struct SomeStudent{ // properties let firstName: String let lastName: String var grade: Int // methods func printGrade(){ print("grade is \(grade)") } } class AnotherStudent { // properties let firstName: String let lastName: String var grade: Int // methods init(firstName: String, lastName: String, grade: Int){ self.firstName = firstName self.lastName = lastName self.grade = grade } func printGrade

[swift] 함수(fuction)의 기본 개념정리

이미지
[swift] 함수(fuction) 정리 같은 코드를 복사 붙여넣기 하면서 쓰지 않기 위해 함수를 사용한다. 함수의 기능에 대해 정리하면서 남긴 기록. 정의하는 방법 사용법은 간단하다 func 키워드 뒤에 함수 이름과 ()를 붙여주면된다. func printHello(){ print("hello") } 사용하는 방법 간단하다 함수이름과 빈()를 붙여주면 된다. printHello() // hello 출력 인자 넘겨주기 ()사이에 이름과 타입을 명시해주면 된다. let speedLimit = 100 let mySpeed = 80 func printSpeedViolationStatus(speed: Int){ print(speed > speedLimit ? 'Speed violation!' : 'Keep driving.') } printSpeedViolationStatus(speed: mySpeed) // Keep driving. 여러개의 인자를 넘겨주는 방법은 , 로 추가해서 넘겨준다 let speedLimit = 80 let mySpeed = 100 func printSpeedViolationStatus(speed: Int, speedLimit: Int){ print(speed > speedLimit ? 'Speed violation!' : 'Keep driving.') } printSpeedViolationStatus(speed: mySpeed, speedLimit: speedLimit) // Speed violation! 인자 기본 값(Default Parameter Values) 기본값을 넣을 수 있다. speedLimit: Int = lowLimit 와 같이 작성한다. let mySpeed = 100 let lowLimit = 80 func printSpeedViolationStatus

[WEB] 프론트엔드 개발자가 보면 좋은 페이지들

이미지
[WEB] 프론트엔드 개발가자 보면 좋은 페이지들 프론트엔드 기초 공부를 마친 개발자가 보면 좋을 페이지들을 소개한다. css-tricks 링크 : https://css-tricks.com/ css의 트릭과 html과 관련된 아티클 snippet 제공 codrops 링크 : http://tympanus.net/codrops/ html, css, js 관련 아티클, 튜토리얼 tutorialzine 링크 : https://tutorialzine.com/tag/html html, css, js 관련 아티클과 라이브러리에 대한 정보 제공 csslayout 링크 : https://csslayout.io/ css를 이용해 만든 레이아웃과 패턴들을 공유해주는 페이지 scotch 링크 : https://scotch.io/ React, Vue, Javascript, angular등의 튜토리얼 제공 codecombat 링크 : https://codecombat.com/ Javascript 문법을 이용해 게임을 할 수 있는 곳 flexboxfroggy 링크 : https://flexboxfroggy.com/#ko css 문법을 이용해 게임을 할 수 있는 곳

[IOS] Sign In With Apple 살펴보기

이미지
Sign In With Apple 살펴보기 Sign in with Apple 애플 아이디로 로그인을 할 수 있는 Sign in with Apple이 공개 된 후 적용하고 이해한 내용을 기록으로 남겨둔다. 참고 URL : https://developer.apple.com/documentation/authenticationservices/adding_the_sign_in_with_apple_flow_to_your_app 순서 : https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple#see-also 버튼 추가 새 프로젝트를 만들고 ViewController에 버튼을 호출하기 위한 함수를 추가한다. import AuthenticationServices 해준다. @IBOutlet weak var loginProviderStackView: UIStackView! 프로퍼티를 추가한다. func setupProviderLoginView() { let authorizationButton = ASAuthorizationAppleIDButton() authorizationButton.addTarget(self, action: #selector(handleAuthorizationAppleIDButtonPress), for: .touchUpInside) self.loginProviderStackView.addArrangedSubview(authorizationButton) } @objc func handleAuthorizationAppleIDButtonPress() { } 인증 버튼 동작 extension ViewController: ASAuthorizationControllerDelegate { } exte

[swift] 오버로딩(overloading)과 오버라이딩(overriding)

이미지
오버로딩(overloading)과 오버라이딩(overriding) 오버로딩과 오버라이딩 오버로딩과 오버라이딩에 대해 정리해 놓는다. 오버로딩(overloading) 오버로딩이란 같은 이름의 메소드에 매개변수는 다르게 선언 할 수 있는 것을 의미한다. class Student { var name: String var age: Int? init(name: String, age: Int?) { self.name = name self.age = age } func printInfo(){ print("my name is \(name)") } func printInfo(age: Int){ print("my name is \(name) my age is \(age)") } } var hyunho = Student(name: "hyunho", age: nil) var jihye = Student(name: "jihye", age: 1) hyunho.printInfo() jihye.printInfo(age: jihye.age!) // my name is hyunho // my name is jihye my age is 17 위의 코드에서 이름은 필수지만 나이는 옵션이다. 이 때 자기소개 출력 함수의 경우 이름만 있을 경우와 이름과 나이가 있는경우에 다른 결과가 출력 되어야 하기 때문에 오버로딩을 통해 다른 결과를 출력했다. 오버라이딩(overriding) 상위 클래스에서 선언한 메서드를 하위 클래스에서 재정의해서 사용하는 것. class Student { var name: String var age: Int? init(name: String, age: Int?) { self.n

[swiftUI] List tutorial

이미지
[swiftUI] List tutorial 리스트(List) 리스트는 목록을 구현할 때 사용된다. 여러 데이터를 위에서 아래로 나열 할 때 사용한다. 정적 리스트(Static List) List 안에 Text(“내용”)을 반복적으로 넣어주면 리스트로 나열된다. 단쉰히 기존에 사용자가 입력 해 놓은 값들을 나열 해 줄 뿐이다. 정적 리스트는 리스트 안의 뷰를 구별할 수 있는 식별값이 없다. 그렇기 때무에 첫 번째 Leeo와 네 번째 Leeo가 같은 사람인지에 대한 삭별값이 존재하지 않는다. import SwiftUI struct ContentView : View { var body: some View { List{ HStack{ Text("My name is Leeo") Text("Age is 29") } HStack{ Text("My name is Lisa") Text("Age is 17") } HStack{ Text("My name is Sven") Text("Age is 27") } HStack{ Text("My name is Leeo") Text("Age is 29") } } } } 동적 리스트(Dynamic List) 동적 리스트는 앱이 실행되는 동안에 리스트 안의 뷰가 추가되고 삭제될 수 있다. 다음

[app review] #01 2020-03-13 Binary Rejected

이미지
[app review] #01 2020-03-13 Binary Rejected 직접 만든 간단한 앱을 앱스토어에 제출했다. 처음 받아보는 리뷰. 결론은 좀 기다려 달라는 내용이어서 해야 할 일은 없어보인다. 처음 제출하는 앱이어서 빠트린 것들이 많을텐데 일단은 게시를 목표로 수정해야겠다. Complement Todo 애플 심사 지침서 읽어보기 https://developer.apple.com/kr/app-store/review/guidelines/ Hello, We are unable to continue this app’s review because your Apple Developer Program account is currently under investigation for not following the App Store Review Guidelines’ Developer Code of Conduct. Common practices that may lead to an investigation include, but are not limited to: - Inaccurately describing an app or service - Misleading app content - Engaging in inauthentic ratings and reviews manipulation - Providing misleading customer support responses - Providing misleading responses in Resolution Center - Engaging in misleading purchasing or bait-and-switch schemes - Engaging in other dishonest or fraudulent activity within or outside of the app During our investig

[swift] Optional값 다루기

이미지
[swift] Optional값 다루기 변수의 타입 뒤에 ? 이 붙어있는 데이터를 사용하다가 자꾸 에러가 떠서 검색해보니 Optional이다. Optional에 대해 이번기회에 정리하려 한다. Optional의 구현 Optional은 enum으로 구현되어있다. enum Optional<T> { case none case some(<T>) } optional의 타입은 generic이다. 그러므로 Int, String 등 모든 타입이 들어갈 수 있다. Optional에는 두 종류가 있는데, 하나는 none이고, 나머지 하나는 some(<타입>) 이다. none은 아직 타입이 설정되지 않은 경우이고, some은 선언 된 타입의 값을 가지고 있다. Optional은 enum으로 구현되어 있지만 enum으로 사용하지 않는 이유는 Optional을 사용할 때마다 switch문을 사용하는 방법이 번거롭기 때문이다. switch문을 사용하면 항상 같은 none과 some에 대한 경우를 구현해야하니 코드가 길어질 것이다. 그래서 ?, !, ?? 등으로 Optional을 사용할 수 있게 만든것이다. 아래 예를 들어 Optional의 특징에 대해 설명한다. 거주민의 차 현황에 대해 입력하는 아래와 같은 코드가 있다. var residentName: String = "John" var age: Int = "23" var carNumber: String = "1422" residentName과 age는 모든 사람이 가지고 있지만 carNumber는 없을 수도 있다. 빈칸을 입려할 수 있지만. 값이 없는 상태를 나타내는 nil값을 넣는 방법도 있다. Optional 사용방법 변수의 타입 뒤에 ? 를 붙여준다. 그러면 해당 타입의 데이터를 입력할 수 있고, 아무값도 아닌 nil값을 입력할 수 있다. var carNumber: St

[IOS] Apple의 인증 체계 - CodeSigning, Certificates, Provisioning Profile

이미지
[IOS] Apple의 인증 체계 - CodeSigning, Certificates, Provisioning Profile IOS 개발을 시작하면서 가장 먼저 겪은 문제가 바로 이 인증서 문제이다. 받은 소스가 빌드가 되지 않았고, 인증서가 맞지 않는다는 에러를 발견했다. 구글링을 통해 인증서를 발급받아서 개발을 하다가, 관리가 안되고 계속 인증서가 필요해서 어떻게 관리하면 좋을지 기록으로 남긴다. 인증서는 왜 필요할까? 애플(apple)은 자신들이 허가한 하드웨어(IOS)에 소프트웨어(어플리케이션)가 동작하도록 승인 수 있다. 매번 앱이 실행될 때마다, 해당 앱이 애플로부터 인증을 받았는지 확인한다. 앱은 실행될 수 있는 권한을 가지고 있어야한다. 하지만 개발자는 애플의 권한이 없기 때문에, 애플에게서 권한을 요청해서 받아야한다. 어떻게 요청하고 무었을 요청해야 하는지 정리한다. 출처 :  http://beankhan.tistory.com/115 개발자 권한 받기 키체인에서 인증서 서멍 요청(Certificate Signing Request) 만들기 인증서 서명 요청서 제출 후 애플에게 권한 받기 애플 개발자 센터에서 바로 요청할 수 있는 것이 아닌, 인증서 서명 요청을 만들어야 한다. 키체인 접근 > 인증서 지원 > 인증 기관에서 인증서 요청 > 이메일 입력 > 인증서 저장 만든 CSR을 이용해 Apple developer > Certificates, Identifiers & Profiles > Certificates > +버튼(add) > 개발용 / 배포용 선택 > CSR업로드 위 단계를 완료하면 개발용/배포용 인증서를 발급받을 수 있다. 다운 받은 인증서를 실행하면, 나는 애플대신 소프트웨어(어플리케이션)을 실행할 수 있는 권한이 생긴다. 키 체인의 내 인증서에도 추가된다. Provisio

[xcode] quick help (주석 설명) 사용 방법

이미지
xcode quick help 사용 방법 Xcode에서 Option + Left-click 을 통해 프로퍼티나 메소드에 대한 정보를 얻을 수 있다. 이 정보를 quick help라고 한다. 아래와 같은 코드가 있을 때 quick help를 통해 어떤 정보를 얻을 수 있는지 살펴보자. struct Car { let speed: Int let modelName: String func stopCar() -> Bool{ return true } } let benz = Car(speed: 30, modelName: "benz") benz.stopCar() 메소드에서 quick help를 사용하면 선언된 간략한 정보들을 얻을 수 있다. 프로퍼티의 경우에는 선언 부분을 볼 수 있고, 메소드의 경우에는 매개변수와 반환 값 등을 볼 수 있다. Declaration : 프로퍼티나 메소드의 정의 부분을 보여준다. Parameters : 매개변수의 정보를 보여준다. DeclaredIn : 어느 파일에 선언되어 있는지 보여준다. 사용자가 주석 블록을 추가함으로써 quick help에 더 많은 정보를 넣을 수 있다. 예를 들면 Parameters의 주석의 블록은 /** */ 기호 사이에 설명을 넣을 수 있다. 다음과 같은 형태를 가지며, 스트럭트의 경 요약과 설명을 메소드의 경우 매개변수와 에러핸들링 반환 값에 대한 설명을 추가할 수 있다. /** Summary에 해당하는 내용 Discussion에 해당하는 내용 - parameters: - grade: 학년 - Throws: 여러 에러가 발생할 수 있습니다. - returns: 학년을 반환합니다. */ 아래의 코드에서 grade가 학생의 점수인지, 학년인지 모호할 수 있기 때문에 주석으로 설명을 넣어주면 좀 더 명확해진다. 물론 이름을 잘

[swift] enum 타입의 사용법 정리

이미지
[swift] enum 타입의 사용법 정리 Enumerations “열거” 임의의 관계를 맺는 값들을 하나의 타입으로 묶은 타입이다. 사용법 enum Fruits { case banana case apple case melon case tomato } 타입지정 각각의 사례항목의 값을 지정하려면 타입을 지정하면 된다. enum Fruits: String { case banana case apple case melon case tomato } // Fruits.banana.rawValue == "banana" 구분 Enum 이름이 다르기 때문에 같은 이름과 타입을 가졌어도 구분할 수 있다. enum SomeEnums: Int{ case one, two, three, four } enum AnotherEnums: Int { case one, two, three, four } var a: SomeEnums = .one // 타입이 분명하므로 헷갈릴 염려가 없다. 케이스 매칭 enum의 항목의 값을 구분해서 쓸 때는 주로 switch case문을 사용한다. let myFavorite: Fruits = .banana switch myFavorite { case .banana print(.banana) case .apple print(.apple) case .melon print(.melon) case .tomato print(.tomato) } 연관값 연관값은 사례항목마다 각 타입값을 다르게 할 수 있다. 바코드를 정의하는 방법은 2가지가 있을 수 있다. 1차원과 2차원. enum을 사용하면, 이렇게 2종류의 타입을 정의 할 수 있다. enum Barcode { case upc(Int, Int, Int, Int) case qrCode(String) } var productB

[IOS] CocoaPods과 Carthage과 Swift Package Manager

이미지
asd 개발을 할 때, 내가 사용하고 싶은 기능을 모두 만들어서 쓰기에는 시간이 모자랍니다. 그러기에 다른 라이브러리를 가져다 쓰지만, 업데이트 될 때마다 일일이 최신버젼으로 업데이트 한다는 것은 정말 손이 많이갑니다. 1~2개라면 모르지만 10~20개의 라이브러리들을 사용하게 된다면 귀찮은게 문제가 아니라 물리적으로 불가능 해집니다. 내 프로젝트에 사용할 프로젝트를 연결해주고 명령어 한번으로 해당 프로젝트의 버전을 최신 버전으로 업데이트 해주는 기능이 필요합니다. 이럴 때 필요한게 패키지 매니져이다. 비슷한 기능으로 자바에는 Maven,Gradle Node.js에는 npm 등이 있습니다. Swift 프로젝트에는 크게 CocoaPods ,Carthage 그리고 SPM이 있다. 어떤 차이가 있는지 알아봅시다. 패키지 매니저 골라골라! Cocoapod, Carthage, SPM from hyunho Lee 링크 : https://let-us-go-2020-summer.vercel.app CocoaPods CocoaPods은 가장 오래된 스위프트 패키지 매니져 중 하나입니다. 필요한 오픈소스 라이브러리들을 검색해 내 프로젝트에서 사용하는데 도움을 준다. https://cocoapods.org/ 에서 pod검색이 가능합니다. install 명령어 하나로 fetch 후 dependencies들을 build 한 후 프로젝트에 추가해준다. 정말 편합니다. 설치 $ sudo gem install cocoapods 시작 $ pod init Podfile 내부에 pod 'ObjectMapper', '~> 3.4’ 추가 명시한 라이브러리를 프로젝트에 설치 $ pod install .xcworkspace 생성 podfile이란 CocoaPods을 통해 라이브러리(pod)들을 관리할 수 있는 파일입니다. 어떤 라이브러리가 내 앱에 종속되는지 버전은 몇인지. 업데이트 등