StoryCode

TableView 샘플.ViewController.swift

iOS/XCode Swift
반응형

TableView.swift


import UIKit




class ViewController: UIViewController {

    @IBOutlet var myTableView:UITableView!

    var items: [String] = ["We", "Heart", "Swift"]


    override func viewDidLoad() {

        super.viewDidLoad()

        self.myTableView.register(UITableViewCell.self, forCellReuseIdentifier:"cell")

        self.view.addSubview(self.myTableView)

        //self.tableView.backgroundColor = UIColor.red

        // Do any additional setup after loading the view, typically from a nib.

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

    {

        return self.items.count

    }

    

    func tableView(_ tableView:UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

    {

        let cell:UITableViewCell = self.myTableView.dequeueReusableCell(withIdentifier: "TableViewCell")! as UITableViewCell

        

        cell.textLabel?.text = self.items[indexPath.row]

        return cell

    }


    func tableView(_ tableView:UITableView, didSelectRowAt indexPath: IndexPath)

    {

        print("You selected cell #\(indexPath.row)!")

    }

    

    func numberOfSections(in tableView:UITableView) -> Int

    {

        return 1;

    }


}

 

반응형

'iOS > XCode Swift' 카테고리의 다른 글

애플 Swift Standard Library  (0) 2018.05.16
Swift.org  (0) 2018.05.16
용어 정리  (0) 2018.05.16
Mac, XCode, Swift 버전 확인  (0) 2018.05.15
아웃렛 연결하기  (0) 2018.05.15

용어 정리

iOS/XCode Swift
반응형

Workspace 

 하나 이상의 프로젝트(들)로 이루어지며, 보통 이 프로젝트들은 서로 연관이 있다.

 Project

 코드와 리소스 등을 갖고 있다.

 Target

 각 프로젝트는 하나 이상의 타겟을 갖고 있다.

각 타겟은 프로젝트의 빌드 설정을 정의한다.

각 타겟은 또한 빌드 시 포함하거나 사용할 클래스, 리소스, 커스텀 스크립트들을 정의한다.

타겟은 보통 같은 프로젝트의 서로 다른 배포본을 위해 사용한다.

예를 들어 내 프로젝트는 두 개의 타겟을 갖고 있는데, “보통”의 빌드가 하나 있고 별도의 테스트 기능들, 몇 개의 배경음악, 배경음악을 변경하는 버튼을 갖는 “회사” 빌드가 있다 (유료 / 무료 버전을 각각 정의할 때도 사용할 수 있다).

(프로젝트에) 클래스나 리소스를 추가할 때, 어느 타겟에 포함시킬지도 결정한다.

어떤 클래스/리소스가 어떤 타겟에 포함될지 선택할 수 있다.

예를 들어 “회사” 빌드에는 “DebugHandler” 클래스가 포함된다.

테스트(TDD)를 추가할 경우, 이것 역시 새로운 타겟을 추가 시킨다.

 Scheme

 “Build”, “Test”, “Profile” 등을 수행할 때 어떤 동작을 할지 정의한다.

보통 각 타겟은 하나 이상의 스킴을 갖는다.

Scheme > Manage Schemes 에서 “Autocreate Schemes Now”를 선택해서 타겟의 스킴을 자동 생성할 수 있다.

An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute. (스킴은 빌드할 타겟들의 집합, 빌드할 때 사용할 설정, 수행할 테스트들의 집합을 정의한다. – Apple Doc)


참조)

http://suho.berlin/engineering/ios/ios-workspace-project-target-scheme/?ckattempt=1

반응형

'iOS > XCode Swift' 카테고리의 다른 글

Swift.org  (0) 2018.05.16
TableView 샘플.ViewController.swift  (0) 2018.05.16
Mac, XCode, Swift 버전 확인  (0) 2018.05.15
아웃렛 연결하기  (0) 2018.05.15
Error) signal SIGABRT  (0) 2018.05.15

Mac, XCode, Swift 버전 확인

iOS/XCode Swift
반응형

XCode 버전별로 명령들이 상당히 다르다.


현재 Mac 은 10.13.4 HighSierra 이고, XCode 9.3.1 ( 9E501 ) 이다.


그리고, Swift 버전은 4.1 이다.


* Swift 버전을 알아내는 방법


터미널을 하나 띄운 뒤,

xcrun swift --version

실행

반응형

'iOS > XCode Swift' 카테고리의 다른 글

TableView 샘플.ViewController.swift  (0) 2018.05.16
용어 정리  (0) 2018.05.16
아웃렛 연결하기  (0) 2018.05.15
Error) signal SIGABRT  (0) 2018.05.15
Swift 언어 기본 정리표  (0) 2018.05.15

아웃렛 연결하기

iOS/XCode Swift
반응형

1. ViewController.swift 에서 

@IBOutlet var myTableView:UITableView! 코드 작성후


2. 스토리보드에서 아래와 같이 연결한다.


반응형

'iOS > XCode Swift' 카테고리의 다른 글

용어 정리  (0) 2018.05.16
Mac, XCode, Swift 버전 확인  (0) 2018.05.15
Error) signal SIGABRT  (0) 2018.05.15
Swift 언어 기본 정리표  (0) 2018.05.15
Error) Xcode Safe Area Layout Guide before iOS 9.0  (0) 2018.05.14

Error) signal SIGABRT

iOS/XCode Swift
반응형

해볼 수 있는 것들.


1) 'Menue --> Product --> Clean'

혹은 Shift + CMD + D


2) 아울렛이 여러개이거나, 혹시 아울렛 변수명을 바꾸었을 경우 삭제후 다시 연결




3) 껏다 켜기


반응형

'iOS > XCode Swift' 카테고리의 다른 글

용어 정리  (0) 2018.05.16
Mac, XCode, Swift 버전 확인  (0) 2018.05.15
아웃렛 연결하기  (0) 2018.05.15
Swift 언어 기본 정리표  (0) 2018.05.15
Error) Xcode Safe Area Layout Guide before iOS 9.0  (0) 2018.05.14

Swift 언어 기본 정리표

iOS/XCode Swift
반응형
참고 : https://www.gitbook.com/book/devxoul/ios-with-swift-in-40-hours


변수var name = "1234";var name:String = "1234";String, Int = Type Annotation(타입 어노테이션)
타입추론 = Type Inference(타입 인퍼런스)
상수let name = "1234";let name: Int = 1234;
let name: Float = 1.234;
형변환Float(name)
스트링 합치기String(birthyear) + "년에 태어난 " + name + "아 안녕!"
=
"\(birthyear)년에 태어난 \(name)아 안녕!"
배열var lang = ["swift", "ObjC", "Python"]
var lang:[String] = ["swift", "ObjC", "Python"]
var lang:[String] = []
== var lang = [String]()
lang[0]

() 는 생성자
딕셔너리var cap = ["한국":"서울", "일본":"도쿄"]
var cap:[String:String] = ["한국":"서울", "일본":"도쿄"]
var cap:[String:String] = [:]
== var cap = [String:String]()
cap["한국"]

() 는 생성자
조건문
if age >= 8 && age < 14 {
student = "초등학생"
} else if age < 17 {
student = "중학생"
} else if age < 20 {
student = "고등학생"
} else {
student = "기타"
}
! number : 오류
switch age {
case 8..<14:
student = "초등학생"
case 14..<17:
student = "중학생"
case 17..<20:
student = "고등학생"
default:
student = "기타"
}
위 if 문과 동일한 문구임.
if name.isEmpty
{
}
반복문
for language in languages {
print("저는 \(language) 언어를 다룰 수 있습니다.")
}
배열 반복문
for (country, capital) in capitals {
print("\(country)의 수도는 \(capital)입니다.")
}
딕셔너리 반복문
for i in 0..<100 {
i
}
for _ in 0..<10 {
print("Hello!")
}

변수없이 무의미한 반복
var i = 0
while i < 100 {
i += 1
}
옵셔널 ( Optional )
오류발생)
var name1 : String = "홍길동"
name = nil => 오류

옵셔널=
? 사용법 ) var name2 : String? = nil
print (email) => nil 출력.
"name1 = name2;" 문장은 오류
사용법 = 멀티 바인딩)

if
let name = optionalName,
let email = optionalEmail
{
print(email) // optionalEmail의 값이 존재한다면 해당 값이 출력됩니다.
}
optionalName 과 optionalEmail 에
값이 있으면 각각 name, email 에 값을
넣고 난 다음,
email 에 값을 넣고 + if 문 내부 실행
var optionalAge: Int? = 22

if
let age = optionalAge, age >= 20 {
// age의 값이 존재하고, 20 이상입니다.
}
두번째 let 에 age >= 20 같은 일반문장도 사용가능
- array 가 nil 이 아니면, Empty 가 아닌지 체크하는 방법)

let array: [String]? = []
var isEmptyArray = false

if let array = array, array.isEmpty {
isEmptyArray = true
} else {
isEmptyArray = false
}

- 옵셔널 체이닝(Chaining) 으로 위 if 문 줄여쓰는 방법
if let isEmptyArray = array?.isEmpty == true
1) array가 nil인 경우
array?.isEmpty
~~~~~~
여기까지 실행되고 `nil`을 반환합니다.

2) array가 빈 배열인 경우
array?.isEmpty
~~~~~~~~~~~~~~
여기까지 실행되고 `true`를 반환합니다.

3) array에 요소가 있는 경우
array?.isEmpty
~~~~~~~~~~~~~~
여기까지 실행되고 `false`를 반환합니다.

주의) isEmpty 는 true/ false 반환인데,
옵셔널은 true/ false/ nil 반환이므로,
if 문에서 == true 비교 필요
또다른 옵셔널)
옵셔널이지만, 일반변수 취급하기


optionalEmail
!
! 를 ImplicitylyUnwrappedOptional 이라 호칭
함수와 클로저
함수 1) "-> String" 은 리턴 타입

func hello(name: String, time: Int) -> String {
var string = ""
for _ in 0..<time {
string += "\(name)님 안녕하세요!\n"
}
return string
}

함수호출시)
파라미터 이름 같이 기재
hello(name: "전수열", time: 3)
함수 2)
func hello(to name: String, numberOfTimes time: Int) {
// 함수 내부에서는 `name`과 `time`을 사용합니다.
for _ in 0..<time {
print(name)
}
}

함수호출시) 파라미터명 다르게 하기
hello(to: "전수열", numberOfTimes: 3)
// 이곳에서는 `to`와 `numberOfTimes`를 사용합니다.
함수 3) 호출시 파라미터명 빼기
func hello(_ name: String, time: Int) {
// ...
}

함수호출시)
hello("전수열", time: 3) // 'name:' 이 생략되었습니다.
함수 4) 기본값 지정
func hello(name: String, time: Int = 1) {
// ...
}

함수 호출시)
hello("전수열")
함수 5) 파라미터 개수 미지정
func sum(_
numbers: Int...) -> Int {
var sum = 0
for number in
numbers {
sum += number
}
return sum
}

함수 호출시)
sum(1, 2)
sum(3, 4, 5)
함수 6) 함수안의 함수

func hello(name: String, time: Int) {
func message(name: String) -> String {
return "\(name)님 안녕하세요!"
}

for _ in 0..<time {
print(message(name: name))
}
}
함수 7) 함수안의 함수 리턴해서, 그 함수 사용하기
설명) -> (String) -> String : "String 받아서 Stringw 리턴하는 함수" 를 리턴
func helloGenerator(message: String) -> (String) -> String {
func hello(name: String) -> String {
return name + message
}
return hello
}

let hello = helloGenerator(message: "님 안녕하세요!")
hello("전수열")
다른 케이스)
func helloGenerator(message: String) -> (String, String) -> String {
func hello(firstName: String, lastName: String) -> String {
return lastName + firstName + message
}
return hello
}

let hello = helloGenerator(message: "님 안녕하세요!")
hello("수열", "전")
함수 8) 클로저 ( 사실은, 함수는 이름있는 클로저 다.)

위 함수 줄임형태 1)
func helloGenerator(message: String) -> (String, String) -> String {
return { (firstName: String, lastName: String) -> String in
return lastName + firstName + message
}
}

줄임형태1 을 다시 줄임형태 2)
func helloGenerator(message: String) -> (String, String) -> String {
return {
return $0 + $1 + message
}
}

줄임형태2 을 다시 줄임형태 3)
func helloGenerator(message: String) -> (String, String) -> String {
return { $1 + $0 + message }
}
함수 9) 클로저 변수

let hello: (String, String) -> String = { $1 + $0 + "님 안녕하세요!" }
hello("수열", "전")

let hello: ((String, String) -> String)?
hello?("수열", "전")
함수 10) 클로저 파라미터

func manipulate(number: Int, using block: Int -> Int) -> Int {
return block(number)
}

manipulate(number: 10, using: { (number: Int) -> Int in
return number * 2
})

간략화)
manipulate(number: 10, using: {
$0 * 2
})

간략화 추가)
만약 함수의 마지막 파라미터가 클로저라면, 괄호와 파라미터 이름마저 생략해버릴 수 있습니다.
manipulate(number: 10) {
$0 * 2
}
함수 11) 클로저 활용

클로저는 Swift의 굉장히 많은 곳에서 사용됩니다. 바로 위에서 예시를 든 것처럼 sort()나 filter()와 같은 배열에 많이 쓰입니다. 대표적인 메서드로는 sort(), filter(), map(), reduce()가 있습니다. sort()와 filter()는 바로 위에서 써봤으니 map()과 reduce()에 대해서 살펴볼까요?
map()은 파라미터로 받은 클로저를 모든 요소에 실행하고, 그 결과를 반환합니다. 예를 들어, 정수 배열의 모든 요소들에 2를 더한 값으로 이루어진 배열을 만들고 싶다면, 이렇게 작성할 수 있습니다.
let arr1 = [1, 3, 6, 2, 7, 9]
let arr2 = arr1.map { $0 * 2 } // [2, 6, 12, 4, 14, 18]
reduce()는 초깃값이 주어지고, 초깃값과 첫 번째 요소의 클로저 실행 결과, 그리고 그 결과와 두 번째 요소의 클로저 실행 결과, 그리고 그 결과와 세 번째 요소의 클로저 실행 결과, ... 끝까지 실행한 후의 값을 반환합니다. 바로 위에서 정의한 arr1의 모든 요소의 합을 구하고 싶다면, 아래와 같이 작성할 수 있습니다.
arr1.reduce(0) { $0 + $1 } // 28
첫 번째 인자로 주어진 0부터 시작해서, 각 요소들과의 주어진 클로저에 대한 실행 결과를 바로 다음 요소와 실행합니다. 처음에는 0과 1을 더해서 1, 그 결과인 1과 3을 더해서 4, 그리고 4와 6을 더해서 10, 10과 2를 더해서 12, 12와 7을 더해서 19, 그리고 19와 9를 더해서 28이 반환됩니다.
Tip: Swift에서는 연산자도 함수입니다. 함수는 곧 클로저이기 때문에 연산자는 클로저입니다. 1 + 2를 실행하면, +라는 이름을 가진 연산자 함수가 실행됩니다. 파라미터로는 1과 2가 넘겨지게 됩니다. 즉, + 함수는 파라미터 두 개를 받아서 합을 반환하는 클로저입니다. { $0 + $1 } 인거죠. 그렇기 때문에, 이런 문법도 가능해집니다. +라는 연산자를 클로저로 넘겨버리는 거죠.
arr1.reduce(0, +) // 28
클래스와 구조체
1) 클래스와 구조체

class Dog {
var name: String?
var age: Int?

func simpleDescription() -> String {
if let name = self.name {
return "🐶 \(name)"
} else {
return "🐶 No name"
}
}
}

struct Coffee {
var name: String?
var size: String?

func simpleDescription() -> String {
if let name = self.name {
return "☕️ \(name)"
} else {
return "☕️ No name"
}
}
}

var myDog = Dog()
myDog.name = "찡코"
myDog.age = 3
print(myDog.simpleDescription()) // 🐶 찡코

var myCoffee = Coffee()
myCoffee.name = "아메리카노"
myCoffee.size = "Venti"
print(myCoffee.simpleDescription()) // ☕️ 아메리카노
* 클래스는 Call By Reference, 구조체는 Call By Value
2) 상속

class Animal {
let numberOfLegs = 4
}

class Dog: Animal {
var name: String?
var age: Int?
}

var myDog = Dog()
print(myDog.numberOfLegs) // Animal 클래스로부터 상속받은 값 (4)
3) 생성자

class Dog {
var name: String?
var age: Int?

init() {
self.age = 0
}
}

struct Coffee {
var name: String?
var size: String?

init() {
self.size = "Tall"
}
}
var 변수는 초기값이 필수. 단 옵셔널 제외
4) 상속클래스 생성자

class Dog: Animal {
var name: String?
var age: Int

override init() {
self.age = 0 // 초깃값 설정
super.init() // 변수초기화 후 상위 클래스 생성자 호출
print(self.simpleDescription()) // 상위 생성자 이후 여기서부터 `self` 접근 가능
}

func simpleDescription() -> String {
if let name = self.name {
return "🐶 \(name)"
} else {
return "🐶 No name"
}
}
}
만약 상속받은 클래스라면 생성자에서 상위 클래스의 생성자를 호출해주어야 합니다. 만약 생성자의 파라미터가 상위 클래스의 파라미터와 같다면, override 키워드를 붙여주어야 합니다. super.init()은 클래스 속성들의 초깃값이 모두 설정 된 후에 해야 합니다. 그리고 나서부터 자기 자신에 대한 self 키워드를 사용할 수 있습니다.
5) 파괴자
* 메모리에서 해제된 직후에 호출됨.

class Dog {
// ...

deinit {
print("메모리에서 해제됨")
}
}
6) get, set : Property

struct Hex {
var decimal: Int?
var
hexString: String? {
get {
if let decimal = self.decimal {
return String(decimal, radix: 16)
} else {
return nil
}
}
set {
if let newValue = newValue {
self.decimal = Int(newValue, radix: 16)
} else {
self.decimal = nil
}
}
}
}

var hex = Hex()
hex.decimal = 10
hex.
hexString // "a"

hex.
hexString = "b"
hex.decimal // 11


* 생략시 디폴트 get
class Hex {
// ...

var hexCode: String? {
if let hex = self.hexString {
return "0x" + hex
}
return nil
}
}
Property
- var, let 으로 선언된 변수는 모두 Stored Property
- get, set 은 Computed Property

라고 부른다.
7) willset, didSet : get, set 호출 전/후 에 실행

struct Hex {
var decimal: Int? {
willSet {
print("\(self.decimal)에서 \(
newValue)로 값이 바뀔 예정입니다.")
}
didSet {
print("\(
oldValue)에서 \(self.decimal)로 값이 바뀌었습니다.")
}
}
}
바뀌기전후의 값을 newValue 와 oldValue 값으로 읽을 수 있다.
튜플 (Tuple)- 튜플Tuple은 어떠한 값들의 묶음입니다.
배열 딕셔너리와 비슷하지만, 길이가 고정. 값에 접근할 때에도 [] 대신 .을 사용

Case 1) 인덱스 접근
var coffeeInfo = ("아메리카노", 5100)
coffeeInfo.0 // 아메리카노
coffeeInfo.1 // 5100
coffeeInfo.1 = 5100

Case 2) 네임 접근
var namedCoffeeInfo = (coffee: "아메리카노", price: 5100)
namedCoffeeInfo.coffee // 아메리카노
namedCoffeeInfo.price // 5100
namedCoffeeInfo.price = 5100

Case 3) 선언
var coffeeInfo: (String, Int)
var namedCoffeeInfo: (coffee: String, price: Int)

Case 4) 응용하여 여러 변수 동시 값 지정
let (coffee, price) = ("아메리카노", 5100)
coffee // 아메리카노
price // 5100

Case 5) 값 무시
let (_, latteSize, lattePrice) = ("라떼", "Venti", 5600)
latteSize // Venti
lattePrice // 5600

Case 6) 튜플 변환
func coffeeInfo(for name: String) -> (name: String, price: Int)? {
let coffeeInfoList: [(name: String, price: Int)] = [
("아메리카노", 5100),
("라떼", 5600),
]
for coffeeInfo in coffeeInfoList {
if coffeeInfo.name == name {
return coffeeInfo
}
}
return nil
}

coffeeInfo(for: "아메리카노")?.price // 5100
coffeeInfo(for: "에스프레소")?.price // nil

let (_, lattePrice) = coffeeInfo(for: "라떼")!
lattePrice // 5600
이넘 (Enum)
enum Month: Int
{
case january = 1
case february
...
case november
case december

func simpleDescription() -> String {
switch self {
case .january:
return "1월"
case .february:
return "2월"
...
case .november:
return "11월"
case .december:
return "12월"
}
}
}

사용법 1)
let december = Month.december
print(december.simpleDescription()) // 12월
print(december.rawValue) // 12

사용법 2) 숫자로 Enum 가져오기. 없을경우 nil
let october = Month(rawValue: 10)
print(october) // Optional(Month.october)
1)
enum IssueState: String {
case open = "open"
case closed = "closed"
}


2)
enum Spoon {
case dirt
case bronze
case silver
case gold

func simpleDescription() -> String {
switch self {
case .dirt:
return "흙수저"
case .bronze:
return "동수저"
case .silver:
return "은수저"
case .gold:
return "금수저"
}
}
}

let spoon: Spoon = .gold
doSomething(with: .silver)

func doSomething(with spoon: Spoon) {
// ...
}
doSomething(with: .silver) // 함수 정의에 타입 어노테이션이 있기 때문에 생략 가능
1) Associated Values Enum

enum NetworkError {
case invalidParameter(String, String)
case timeout
}

let error: NetworkError = .invalidParameter("email", "이메일 형식이 올바르지 않습니다.")

if case .invalidParameter(let field, let message) = error {
print(field) // email
print(message) // 이메일 형식이 올바르지 않습니다.
}

switch error {
case .invalidParameter(let field, let message):
print(field) // email
print(message) // 이메일 형식이 올바르지 않습니다.

default:
break
}
1) 옵셔널은 Enum

public enum Optional<Wrapped> {
case
none
case some(Wrapped)
}

let age: Int? = 20

switch age {
case .none: // `nil`인 경우
print("나이 정보가 없습니다.")

case .some(let x) where x < 20:
print("청소년")

case .some(let x) where x < 65:
print("성인")

default:
print("어르신")
}
프토토콜(Protocol)
1) 프로토콜Protocol은 인터페이스

protocol Sendable {
var from: String? { get }
var to: String { get }

func send()
}

struct Mail:
Sendable {
var from: String?
var to: String

func send() {
print("Send a mail from \(self.from) to \(self.to)")
}
}

struct Feedback:
Sendable {
var from: String? {
return nil // 피드백은 무조건 익명으로 보냅니다.
}
var to: String

func send() {
print("Send a feedback to \(self.to)")
}
}
* 주요 프로토콜 1) CustomStringConvertible
자기 자신을 표현하는 문자열을 정의합니다.
print(), String() 또는 "\()"에서 사용될 때의 값입니다.

public protocol CustomStringConvertible {
/// A textual representation of `self`.
public var description: String { get }
}

struct Dog: CustomStringConvertible {
var name: String
var description: String {
return "🐶 \(self.name)"
}
}

let dog = Dog(name: "찡코")
print(dog) // 🐶 찡코

* 주요 프로토콜 2) ExpressibleBy - Literal.
struct DollarConverter: ExpressibleByIntegerLiteral {
typealias IntegerLiteralType = Int

let price = 1_177
var dollars: Int

init(integerLiteral value: IntegerLiteralType) {
self.dollars = value * self.price
}
}

let converter: DollarConverter = 100
converter.dollars // 117700
* Any와 AnyObject

Any는 모든 타입에 대응합니다. AnyObject는 모든 객체Object에 대응합니다.
let anyNumber: Any = 10
let anyString: Any = "Hi"

let anyInstance: AnyObject = Dog()

Any와 AnyObject는 프로토콜입니다. Swift에서 사용 가능한 모든 타입은 Any를 따르도록 설계되었고, 모든 클래스들에는 AnyObject 프로토콜이 적용되어있습니다.
* 타입 캐스팅 (Type Casting)

anyNumber에 10을 넣었다고 해서 anyNumber가 Int는 아닙니다.
'Any 프로토콜을 따르는 어떤 값'이기 때문이죠.

anyNumber + 1 // 컴파일 에러!

이럴 때에는 as를 이용해서 다운 캐스팅Down Casting을 해야 합니다.
Any는 Int보다 더 큰 범위이기 때문에, 작은 범위로 줄인다고 하여 '다운 캐스팅'입니다.

Any는 Int 뿐만 아니라 String과 같은 전혀 엉뚱한 타입도 포함되어 있기 때문에 무조건 Int로 변환되지 않습니다.
따라서 as?를 사용해서 옵셔널을 취해야 합니다.

let number: Int? = anyNumber as? Int

옵셔널이기 때문에, 옵셔널 바인딩 문법도 사용할 수 있습니다. 실제로 이렇게 사용하는 경우가 굉장히 많습니다.
if let number = anyNumber as? Int {
print(number + 1)
}


* 타입 검사
print(anyNumber is Int) // true
print(anyNumber is Any) // true
print(anyNumber is String) // false
print(anyString is String) // true
익스텐션(Extension)1) 이미 정의된 타입에 새로운 속성이나 메서드를 추가

extension String {
var length: Int {
return self.characters.count
}

func reversed() -> String {
return self.characters.reversed().map { String($0) }.joined(separator: "")
}
}

let str = "안녕하세요"
str.length // 5
str.reversed() // 요세하녕안


반응형

'iOS > XCode Swift' 카테고리의 다른 글

용어 정리  (0) 2018.05.16
Mac, XCode, Swift 버전 확인  (0) 2018.05.15
아웃렛 연결하기  (0) 2018.05.15
Error) signal SIGABRT  (0) 2018.05.15
Error) Xcode Safe Area Layout Guide before iOS 9.0  (0) 2018.05.14

Error) Xcode Safe Area Layout Guide before iOS 9.0

iOS/XCode Swift
반응형

Safe Area 는 아이폰X 에서 컨텐츠가 짤리지 않도록 가이드 라인을 제시한 것이다.


이걸 켜거나 끌때는, 아래 옵션을 설정하면 된다.



반응형

'iOS > XCode Swift' 카테고리의 다른 글

용어 정리  (0) 2018.05.16
Mac, XCode, Swift 버전 확인  (0) 2018.05.15
아웃렛 연결하기  (0) 2018.05.15
Error) signal SIGABRT  (0) 2018.05.15
Swift 언어 기본 정리표  (0) 2018.05.15