├── .gitignore ├── 01.Data ├── Literal_Number.swift ├── Literal_Range.swift ├── Literal_String.swift ├── Nil.swift ├── Operator.swift ├── Print.swift ├── Statement.swift └── VarAndConstant.swift ├── 02.Type ├── Bool.swift ├── Character.swift ├── Float.swift ├── Int.swift ├── Range.swift ├── String.swift ├── String_Compare.swift ├── String_Foundation.swift ├── String_IO.swift ├── String_Modify.swift ├── String_Substring.swift ├── String_Views.swift ├── TypeOf.swift └── Unicode.swift ├── 03.CollectionType ├── Array.swift ├── ComplexCollection.swift ├── Dictionary.swift ├── Set.swift ├── Tuple.swift └── ValueType.swift ├── 04.Controls ├── for.swift ├── guard.swift ├── if.swift ├── label.swift ├── switch_case.swift ├── version-check.swift └── while.swift ├── 05.Optional ├── ForcedUnwrapping.swift ├── IUO.swift ├── NilCheck.swift ├── NilCoalescing.swift ├── Optional.swift ├── OptionalBinding.swift └── OptionalChain.swift ├── 06.CustomType ├── Class.swift ├── ComplexType.swift ├── Enum.swift ├── Struct.swift ├── Typealias.swift └── ValueAndReferenceType.swift ├── 07.Function ├── Function.swift ├── NestedFunction.swift ├── OptionalParamReturn.swift ├── Overloading.swift ├── Parameter.swift ├── ParameterDefaultValue.swift ├── ParameterInout.swift └── ParameterVaridic.swift ├── 08.StructAndEnum ├── EnumAndAssociation.swift ├── EnumAndMethod.swift ├── ImmutableAndMutable.swift ├── NestedType.swift ├── PropertyChange.swift ├── StoredAndComputedProperty.swift ├── StructAndInitializer.swift ├── StructAndMethod.swift ├── StructAndMutating.swift └── StructAndStaticMethod.swift ├── 09.Class ├── ClassAndInstance.swift ├── ClassAndMethod.swift ├── ComputedProperty.swift ├── ConvenienceInitializer.swift ├── Deinitializer.swift ├── DesignatedInitializer.swift ├── FailableInitializer.swift ├── InheritanceAndInitializer1.swift ├── InheritanceAndInitializer2.swift ├── InheritanceAndInitializerNotInherited.swift ├── InheritanceAndOverride.swift ├── InheritanceAndRequiredInitializer.swift ├── InitializerAndFailableInitializer.swift ├── PropertyLazy.swift ├── ReferenceType.swift ├── property_observing.swift ├── type_method.swift └── type_property.swift ├── 09.Inheritance ├── example1.swift ├── example2.swift ├── initializer_override_failable.swift ├── super_self.swift └── two_phase_initialization.swift ├── 10.Closure ├── array_sort.swift ├── autoclosure.swift ├── capture.swift ├── capture_reference.swift ├── closure_api.swift ├── closure_inClass.swift ├── escaping.swift ├── function_object.swift └── function_type.swift ├── README.md ├── z.ARC ├── arc_basic.swift ├── collection.swift ├── reference_cycle.swift ├── scope.swift ├── unowned.swift └── weak.swift ├── z.AccessLevels ├── AccessLevel │ ├── AccessLevel.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── AccessLevel │ │ ├── main.swift │ │ └── other.swift │ └── InnerFramework │ │ ├── Info.plist │ │ ├── InnerFramework.h │ │ └── framework.swift └── AccessLevelApp │ ├── AccessLevelApp.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── AccessLevelApp │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift │ └── MyModule │ ├── Info.plist │ ├── MyModule.h │ └── myModules.swift ├── z.DesignPattern ├── delegate1.swift ├── delegate2.swift └── singleton.swift ├── z.ErrorHandling ├── custom_error.swift ├── defer.swift ├── error_closure.swift ├── error_function.swift ├── error_propagation.swift └── use_error_function.swift ├── z.Extension ├── extension.swift ├── extension_existing_type.swift └── extension_struct_enum.swift ├── z.Foundation ├── JsonParsing │ ├── JsonParsing.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── JsonParsing │ │ ├── device.json │ │ └── main.swift ├── archive1.swift ├── archive2.swift ├── array.swift ├── array_file.swift ├── array_mutable.swift ├── data_base64.swift ├── date.swift ├── dictionary.swift ├── dictionary_file.swift ├── fm_copyremove.swift ├── fm_list.swift ├── fm_read.swift ├── json_data.json ├── json_parsing.swift ├── notification.swift ├── nsobject_description.swift ├── nsobject_equal.swift ├── nsobject_typecheck.swift ├── protocol_optional.swift ├── selector.swift ├── selector_ambiguous.swift ├── selector_perform.swift ├── selector_staticMethod.swift ├── string1.swift ├── string2.swift ├── string_file.swift ├── string_mutable.swift ├── string_referenceType.swift ├── thread1.swift ├── thread2.swift ├── timer.swift ├── type_convert.swift ├── url.swift └── url_resource_loading.swift ├── z.Generics ├── custom_type_generics.swift └── generics.swift ├── z.Operator ├── custom_operator.swift ├── equal.swift ├── overloading.swift └── subscript.swift ├── z.Protocol ├── class_only.swift ├── exercise1.swift ├── initializer.swift ├── property.swift ├── protocol_basic.swift ├── protocol_extensioin.swift ├── protocol_type.swift └── static_method.swift └── z.TypeCheck ├── any.swift ├── type_alias.swift ├── type_cast.swift └── type_check.swift /.gitignore: -------------------------------------------------------------------------------- 1 | Sandbox 2 | 3 | # Xcode 4 | # 5 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata 21 | 22 | ## Other 23 | *.xccheckout 24 | *.moved-aside 25 | *.xcuserstate 26 | *.xcscmblueprint 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | 32 | ## Playgrounds 33 | timeline.xctimeline 34 | playground.xcworkspace 35 | 36 | # Swift Package Manager 37 | # 38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 39 | # Packages/ 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | # Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | # Carthage/Checkouts 54 | 55 | Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 63 | 64 | fastlane/report.xml 65 | fastlane/screenshots 66 | -------------------------------------------------------------------------------- /01.Data/Literal_Number.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 리터럴(Literal), Numeric Literals 3 | */ 4 | 5 | let trueValue = true 6 | let falseValue = false 7 | 8 | // 참/거짓 리터럴 9 | print(trueValue) 10 | print(falseValue) 11 | 12 | // 정수형 리터럴 13 | let intValue1 = 1 14 | let intValue2 = 2 15 | print(intValue1) 16 | print(intValue2) 17 | 18 | // 이진수(binary) - 0b로 시작 19 | // 8진수 - 0o 20 | // 16진수 - 0x 21 | 22 | let valueDecimal = 100 23 | let valueBinary = 0b100 // 4 24 | let valueOctal = 0o100 // 64 25 | let valueHexa = 0x100 // 256 26 | // let valueError = 0b210 // Error 27 | 28 | print(valueDecimal) 29 | print(valueBinary) // 4 30 | print(valueOctal) // 64 31 | print(valueHexa) // 256 32 | 33 | // 실수형(Double, Float) 34 | let valueDouble1 = 1.1 35 | let valueDouble2 = 2.2 36 | 37 | // 실수형 38 | print(valueDouble1) 39 | print(valueDouble2) 40 | 41 | // e표현 42 | let valueExponential1 = 1.23e3 // 1230 43 | let valueExponential2 = 1.23e-3 // 0.00123 44 | print(valueExponential1) 45 | print(valueExponential2) 46 | 47 | // exp표현. 16진수만. 결과는 Double 타입 48 | let valueExponential3 = 0x2p6 // 2 * 2^6, 128 49 | let valueExponential4 = 0xFp10 // 15 * 2^10, 1024 50 | 51 | print(valueExponential3) 52 | print(valueExponential4) 53 | -------------------------------------------------------------------------------- /01.Data/Literal_Range.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 범위(Literal) 3 | */ 4 | 5 | // 숫자 범위 리터럴 6 | let closedRange = 1...10 7 | let halfOpenRange = 1..<10 8 | print("closedRange :", closedRange) 9 | print("halfOpenRange :", halfOpenRange) 10 | 11 | // 열린 범위 12 | let oneSideRange1 = 1... 13 | let oneSideRange2 = ..<10 14 | print(oneSideRange1) 15 | print(oneSideRange2) 16 | 17 | // 실수형 열린 범위 18 | let doubleRange = 1.1...2.2 19 | print(doubleRange) 20 | 21 | // 문자 범위 리터럴 22 | let stringRange = "a"..."f" 23 | print(stringRange) 24 | -------------------------------------------------------------------------------- /01.Data/Literal_String.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 리터럴(Literal) 3 | */ 4 | 5 | // 문자형 리터럴 6 | let str1 = "a" 7 | let str2 = "hello" 8 | let str3 = "1" 9 | 10 | print(str1) 11 | print(str2) 12 | print(str3) 13 | 14 | // String Interpolation 15 | 16 | let str4 = "1 + 2 = \(1+2)" 17 | 18 | print(str4) 19 | 20 | // """을 이용한 다열(Multiline) 문자열 21 | // a/nb 22 | let str5 = """ 23 | a 24 | b 25 | """ 26 | 27 | print(str5) 28 | 29 | // a/n b 30 | let str6 = """ 31 | a 32 | b 33 | """ 34 | 35 | print(str6) 36 | 37 | // 에러 38 | /* 39 | let str7 = """ 40 | a 41 | b 42 | """ 43 | print(str7) 44 | */ 45 | 46 | // Error. 다열 문자열(""")을 한줄에 작성하면 에러 47 | /* 48 | let str8 = """ abc """ 49 | print(str8) 50 | */ -------------------------------------------------------------------------------- /01.Data/Nil.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * nil 3 | */ 4 | 5 | // 타입 선언(옵셔널 타입) 필요 6 | let intNilValue: Int? = nil 7 | let strNilValue: String? = nil 8 | 9 | -------------------------------------------------------------------------------- /01.Data/Operator.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Swift의 연산자 3 | */ 4 | 5 | // 대입 연산자(Assignment Operator) 6 | var value1 = -10 7 | let (value2, value3) = (1, 2) // tuple 8 | 9 | // 단항 연산자(Unary Operator) 10 | value1 = -value1 // 10 11 | print(value1) 12 | 13 | value1 = +value1 // -10 14 | print(value1) 15 | 16 | 17 | // 산술 연산자(Arithmetic Operator) : +, -, *, / 18 | 19 | value1 = 10 + 20 20 | value1 = 20 - 10 21 | 22 | let strValue1 = "a" + "b" + "c" // "abc" 23 | 24 | // 나머지 25 | // 정수형 타입 26 | 27 | let reminder1 = 10 % 3 // 1 28 | print(" 10 % 3 :", reminder1) 29 | 30 | // 실수형 타입에서 나머지 연산자 사용 불가(truncatingRemainder 함수 사용) 31 | //let reminder2 = 9.9 % 3.0 32 | 33 | 34 | // 비교 연산자 : ==, !=, >, < >=, <= 35 | // ===, !== (객체 인스턴스 비교) 36 | 37 | 38 | // 3항 연산자(Ternary Operator) 39 | 40 | let ternaryOperatorResult = 1 > 3 ? "A" : "B" 41 | print("Ternary Operator :", ternaryOperatorResult); 42 | 43 | 44 | // nil 병합 연산자(Nil-Coalescing Operator) 45 | var valueCanBeNil: Int? = nil 46 | let nilCoalesceResult1 = valueCanBeNil ?? 99 // 99 47 | print("nil ?? 99 :", nilCoalesceResult1) 48 | 49 | valueCanBeNil = 1 50 | let nilCoalesceResult2 = valueCanBeNil ?? 99 // 1 51 | print("1 ?? 99 :", nilCoalesceResult2) 52 | 53 | /* 54 | * ++, -- 연산자는 삭제. +=, -= 연산자 사용 55 | */ 56 | 57 | /* 58 | var intValue = 10 59 | intValue++ 60 | */ 61 | 62 | 63 | // 논리 연산자 : !a(not), a && b, a || b -------------------------------------------------------------------------------- /01.Data/Print.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * print함수를 이용해서 콘솔에 출력하기 3 | */ 4 | 5 | print(100) 6 | 7 | let value = "Swift" 8 | print(value) 9 | 10 | print("Hello", value) 11 | 12 | print("Hello \(value)") -------------------------------------------------------------------------------- /01.Data/Statement.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Swift 코드 작성 방법 3 | */ 4 | 5 | 6 | // 세미콜론 사용/생략 가능 7 | var value = 10; 8 | value = 20 9 | 10 | // 세미콜론 2개는 에러. ;콜론 단독 문장으로 인식 - 에러 11 | // print(value);; 12 | 13 | // 한줄에 두 문장 작성시 세미콜론 작성 14 | var value2 = 10; value2 = 20; print(value2) 15 | 16 | // 여러 줄에 문장 작성 가능 17 | var value3 18 | = 19 | 100 20 | print(value3) 21 | 22 | // import를 이용한 모듈 로딩 23 | import Foundation 24 | -------------------------------------------------------------------------------- /01.Data/VarAndConstant.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 변수 3 | */ 4 | 5 | // 값과 함게 변수 선언 6 | var value = 10 7 | 8 | // 변수의 값은 변경 가능 9 | value = 20 10 | 11 | // 예약어를 변수로 사용하기 12 | var `default` = 1 13 | var `var` = "Variable" 14 | 15 | // 변수의 타입 작성 16 | var value2: Int = 10 17 | 18 | // 초기값 없이 변수 선언. 단 타입 선언 필요 19 | var value3 : Int 20 | value3 = 10 21 | 22 | // 초기화되지 않은 변수 사용은 에러 23 | var value4 : Int 24 | // error: variable 'value4' used before being initialized 25 | // print(value4) 26 | 27 | // 타입이 다른 값을 대입하면 에러 28 | var value5: Int = 10 29 | // error: cannot assign value of type 'String' to type 'Int' 30 | // value5 = "10" 31 | 32 | 33 | /* 34 | * 상수 35 | */ 36 | 37 | // 값 대입 후 변경 불가 38 | let constant = 10 39 | // Error : 상수의 값은 변경 불가 40 | // constant = 20 41 | 42 | // 타입과 함께 상수 선언과 바인딩 분리 43 | let constant2 : Float 44 | constant2 = 1.23 -------------------------------------------------------------------------------- /02.Type/Bool.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Bool 타입 3 | */ 4 | // Bool 5 | var value = true 6 | 7 | // 타입 선언과 초기화 분리 8 | var value2: Bool 9 | value2 = false 10 | 11 | // Bool타입 상수 12 | let value3: Bool = true 13 | 14 | // 문자열 "true", "false" 에서 타입 변환 (옵셔널) 15 | let value4 = Bool("true") 16 | print("Bool(\"true\") : ", value4!) 17 | 18 | // 문자열에서 변환 실패 - nil. (옵셔널) 19 | let value5 = Bool("YES") 20 | print("Bool(\"YES\") :", value5) 21 | 22 | // 에러 = Bool 타입에 정수값 대입 23 | // error: cannot convert value of type 'Int' to specified type 'Bool' 24 | // var value6 : Bool = 1 25 | -------------------------------------------------------------------------------- /02.Type/Character.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 문자 다루기 3 | */ 4 | let a : Character = "a" 5 | 6 | // Emoji 7 | 8 | let dog : Character = "🐶" 9 | let heart : Character = "♥" 10 | 11 | print("dog: \(dog), heart : \(heart)") 12 | //print("\(dog.unicodeScalars.first?.value), \(heart.unicodeScalars.first?.value)") 13 | 14 | // Character from unicode. Hex value 15 | let u63 : Character = "\u{63}" // c 16 | let u2665 : Character = "\u{2665}" // ♥ 17 | 18 | print("u{63} : ",u63, " - u{2665} : ", u2665) 19 | 20 | // 에러 21 | // let chars : Character = "abc" // String Literal 22 | 23 | // 비교 24 | let c : Character = "c" 25 | print("a > c : ", a > c) // false 26 | print("heart == ♥ : ", heart == "♥") // true 27 | print("🐶 > ♥ : ", dog > heart) 28 | 29 | 30 | -------------------------------------------------------------------------------- /02.Type/Float.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 실수형 값을 다루는 타입은 Float, Double이 있다. 3 | * Float타입의 크기는 4byte, Double 타입의 크기는 8byte 4 | */ 5 | 6 | // 실수형 타입 7 | let doubleVal = 3.14 // 기본 Double 타입 8 | 9 | // Float 타입으로 선언 10 | let floatVal : Float = 36.5 11 | 12 | let floatVal2 = 3e10 // 지수형 표기. 3^10 = 30000000000 13 | 14 | // Double, Float 사이의 연산은 에러 15 | // error: binary operator '+' cannot be applied to operands of type 'Float' and 'Double' 16 | // var ret = floatVal + doubleVal 17 | 18 | // 실수형 타입 간 변환 19 | let floatFromDouble : Float = Float(doubleVal) 20 | print("float from double : ", floatFromDouble) 21 | 22 | // 문자열에서 변환 23 | let doubleFromString = Double("1234")! 24 | print("double from string : ", doubleFromString) 25 | 26 | -------------------------------------------------------------------------------- /02.Type/Int.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 정수형 타입 3 | */ 4 | 5 | var intVal = 1 // 기본 Int 타입 6 | var uintVal : UInt = 2 7 | 8 | // Unsigned Int는 양수만 다룰 수 있다. 9 | // error: negative integer '-2' overflows when stored into unsigned type 'UInt' 10 | // uintVal = -2 11 | 12 | // Int8은 8비트 크기. -128 ~ 127 까지 다룰 수 있다. 13 | var int8Val : Int8 = 3 14 | // error: integer literal '128' overflows when stored into 'Int8' 15 | // int8Val = 128 16 | 17 | // UInt8은 8비트 크기. 0~255까지 다룰 수 있다. 18 | var uint8Val : UInt8 = 255 19 | // error: integer literal '256' overflows when stored into 'UInt8' 20 | // uint8Val = 256 21 | 22 | var int16Val : Int16 = 32767 23 | let uint16Val : UInt16 = 65535 // 0x1p16 - 1 24 | 25 | var int32Val : Int32 = 2147483647 // 0x1p32 - 1 26 | let uint32Val : UInt32 = 4294967295 // 0x1p32 - 1 27 | let int64Val : UInt64 = 18446744073709551615 28 | 29 | // 타입 크기 : .max, .min 30 | print("Int8.max", Int8.max) 31 | print("UInt8.min", UInt8.min) 32 | print("Int.max : \(Int.max), Int.min : \(Int.min)") 33 | 34 | // 2진수 다루기 35 | var binaryVal = 0b1011 // 11 36 | print("binary Value : ", binaryVal) 37 | // 8진수 다루기 38 | var octetVal = 0o77 // 63 39 | print("octec Value : ",octetVal) 40 | // 16진수 다루기 41 | var hexVal = 0xFF // 255 42 | print("hex Value : ",hexVal) 43 | 44 | // 타입 호환 : Int8, Int16, Int32 혼합 연산은 에러 - 타입 변환해야 한다. 45 | //let intResult = intVal + int16Val 46 | let intResult2 = intVal + Int(int16Val) 47 | 48 | // 서로 다른 타입의 값 대입 불가 49 | // error: cannot assign value of type 'Int16' to type 'Int' 50 | //intVal = int16Val 51 | // error: cannot assign value of type 'Int8' to type 'Int32' 52 | //int32Val = int8Val 53 | 54 | // 정수형 타입 간 타입 변환 55 | intVal = Int(int16Val) 56 | int16Val = Int16(int8Val) 57 | 58 | 59 | // 60 | // 다른 타입에서 변환 61 | // 62 | 63 | // Bool 에서 Int 변환 불가 64 | // error: cannot invoke initializer for type 'Int' with an argument list of type '(Bool)' 65 | //let intFromBool = Int(true) 66 | 67 | // 실수형 값에서 Int 변환 68 | let intFromDouble = Int(3.14) 69 | 70 | // 문자열에서 Int 변환. 71 | let intFromString = Int("1234") 72 | // 16진수, 8진수, 2진수 73 | let intFromHexStr = Int("1F4", radix: 16) 74 | let intFromOctStr = Int("123", radix: 8) 75 | let intFromBinStr = Int("1010", radix: 2) 76 | print("Int From HexString(1F4) : ", intFromHexStr!) 77 | print("Int From OctString(123) : ", intFromOctStr!) 78 | print("Int From BinString(1010) : ", intFromBinStr!) 79 | 80 | // 변환에 실패하면 nil. 옵셔널 81 | let intFromOctStrFail = Int("1F5", radix: 8) 82 | print("Int From OctString Fail : ", intFromOctStrFail) 83 | 84 | // 문자가 포함된 문자열 Int 변환 실패 nil. 옵셔널 85 | let intFromStrFail = Int("1234a") 86 | print("Int From String Fail : ", intFromStrFail) 87 | -------------------------------------------------------------------------------- /02.Type/Range.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 범위 타입 3 | */ 4 | 5 | let range1 = 1...10 6 | print("1...10 count :", range1.count) 7 | 8 | // 범위 포함 여부 9 | print("1...10 contains 3 :", range1.contains(3)) 10 | print("1...10 contains 99 :", range1.contains(99)) 11 | 12 | // 바운드 13 | print("1...10 lowerBound :", range1.lowerBound) 14 | print("1...10 upperBound :", range1.upperBound) 15 | 16 | // Range 타입 선언 17 | let range2 : Range = 1..<3 18 | print("Range :",range2) 19 | 20 | let range3 : ClosedRange = 1...4 21 | print("ClosedRange :",range2) 22 | 23 | let range4 : CountableRange = 1..<5 24 | print("CountableRange : ",range4) 25 | 26 | let range5 : PartialRangeThrough = ...10 27 | print("PartialRangeThrough :", range5) 28 | 29 | let emtpyRange = 1...1 30 | print("is Empty : ", emtpyRange.isEmpty) 31 | 32 | // 문자 범위 리터럴 33 | let stringRange : ClosedRange = "a"..."f" 34 | print(stringRange) 35 | -------------------------------------------------------------------------------- /02.Type/String.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 문자열 타입 3 | */ 4 | // 기본 타입은 문자열(String) 5 | let str1 = "Hello, Swift Language" 6 | let str2 : String = "Swift" 7 | 8 | // interpolation 9 | let str3 = "1 + 2 = \(1+2)" 10 | let str4 = "Hello, \(str2)" 11 | print("interpolation1 : ", str3) 12 | print("interpolation2 : ", str4) 13 | 14 | // 문자열 길이 15 | let count1 = str1.count 16 | let count2 = str2.count 17 | print("String Count ", count1, count2) 18 | 19 | // Bool 값에서 문자열 변환 20 | let strFromBool = String(true) 21 | print("String from Bool : \(strFromBool)") // "true" 22 | 23 | // 문자와 문자열 24 | let charVal : Character = "♥" 25 | let strFromChar = String(charVal) 26 | 27 | // 정수형 값에서 문자열 변환 28 | let strFromInt = String(1234) 29 | print("String from Int : \(strFromInt)") 30 | 31 | // 실수형 값에서 문자열 변환 32 | let strFromFloat = String(3.14) 33 | print("String from Float : \(strFromFloat)") 34 | 35 | // String and Character 36 | for ch in "String" { 37 | print("ch : \(ch)") 38 | } -------------------------------------------------------------------------------- /02.Type/String_Compare.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 문자열 비교 3 | */ 4 | 5 | let str = "Hello Swift" 6 | if str == "Hello Swift" { 7 | print("같은 문자열") 8 | } 9 | 10 | print("hasPrefix(Hello) :",str.hasPrefix("Hello")) 11 | print("hasSuffix(ft) :", str.hasSuffix("ft")) 12 | 13 | // 크기 비교 14 | let str1 = "H" 15 | let str2 = "h" 16 | 17 | print("H < h :", str1 < str2) 18 | -------------------------------------------------------------------------------- /02.Type/String_Foundation.swift: -------------------------------------------------------------------------------- 1 | // 파운데이션(Foundation) Framework 로딩 2 | import Foundation 3 | 4 | /** 5 | * 포맷 문자열 만들기 : String(format:) 6 | */ 7 | 8 | 9 | // 포맷 문자열 생성 - 파운데이션 프레임워크 제공 10 | let formatted1 = String(format:"%03d", 12) 11 | print("Formatted String(03d) : ", formatted1) 12 | 13 | let formatted2 = String(format: "%3.2f", 3.14159) 14 | let formatted3 = String(format: "%3.2e", 3.14159) 15 | print("Formatted String(3.2f) : ", formatted2) 16 | print("Formatted String(3.2e) : ", formatted3) 17 | 18 | let formatted4 = String(format: "%@, %@", "Hello", "Swift") 19 | print("formatted String : ", formatted4) 20 | 21 | 22 | /* 23 | * 문자열 비교, 비교 옵션 : compare 24 | */ 25 | 26 | // compare를 이용한 비교. 파운데이션 프레임워크가 제공 27 | let numStr1 = "1" 28 | let numStr2 = "09" 29 | 30 | let ret1 : ComparisonResult = numStr1.compare(numStr2) // orderedDescending 31 | print(ret1 == .orderedDescending) 32 | 33 | let ret2 = numStr1.compare(numStr2, options: .numeric, range: nil, locale: nil) // orderedAscending 34 | print(ret2 == .orderedAscending) 35 | 36 | let ret3 = "hello".compare("HELLO", options: .caseInsensitive, range: nil, locale: nil) // orderedSame 37 | print(ret3 == .orderedSame) 38 | 39 | 40 | /** 41 | * 트리밍 : trimmingCharacters 42 | */ 43 | 44 | // 공백 문자 트리밍 45 | let spaceStr = " Hello Swift " 46 | let trimmed = spaceStr.trimmingCharacters(in: CharacterSet.whitespaces) 47 | print("Trimming WhiteSpace : ", trimmed) 48 | 49 | // 특정 문자 트리밍 50 | let dashStr = "--Hello Swift!-" 51 | // 트리밍할 문자셋 52 | let chSet = CharacterSet(charactersIn: "-") 53 | let trimmed2 = dashStr.trimmingCharacters(in: chSet) 54 | print("Trimming specipic Character : ",trimmed2) 55 | 56 | 57 | /** 58 | * 찾기 : range 59 | */ 60 | let findTargetStr = "Hello Swift" 61 | 62 | // lo 문자열 찾기. range는 파운데이션이 제공 63 | let findRange1 = findTargetStr.range(of: "lo")! 64 | let findRangeLower = findRange1.lowerBound.utf16Offset(in: findTargetStr) 65 | let findRangeUpper = findRange1.upperBound.utf16Offset(in: findTargetStr) 66 | print("lower : \(findRangeLower) - upper : \(findRangeUpper)") 67 | 68 | // sw 문자열 찾기. 찾을 수 없으면 nil 반환 69 | let findRange2 = findTargetStr.range(of:"sw") 70 | if findRange2 == nil { 71 | print(findTargetStr + "에서 sw 못찾음") 72 | } 73 | // sw 문자열 대소문자 구분 없이 찾기. 74 | let findRange3 = findTargetStr.range(of:"sw", options: .caseInsensitive) 75 | if findRange3 != nil { 76 | print(findTargetStr + "에서 대소문자 구분 없이 sw 찾음") 77 | } 78 | -------------------------------------------------------------------------------- /02.Type/String_IO.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | let str = "Hello Swift" 4 | 5 | // 파일로 저장 6 | let filePath = "/Users/wannabewize/Documents/str.txt" 7 | ///Users/wannabewize 8 | do { 9 | try str.write(toFile: filePath, atomically: true, encoding: String.Encoding.utf8) 10 | } 11 | catch { 12 | print("Error") 13 | } 14 | 15 | // 파일에서 읽기 16 | do { 17 | let str2 = try String(contentsOfFile: filePath) 18 | print(str2) 19 | } 20 | catch { 21 | print("Error") 22 | } 23 | -------------------------------------------------------------------------------- /02.Type/String_Modify.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 문자열 덧붙이기 : +, append 3 | */ 4 | 5 | var str = "Hello" 6 | str = str + " Swift" 7 | str += "!" 8 | print(str) 9 | 10 | var str2 = "Hello" 11 | str2.append(" Swift") 12 | print(str2) 13 | 14 | let exclaim : Character = "!" 15 | str2.append(exclaim) 16 | print(str2) 17 | 18 | /* 19 | * 대소문자 변경: uppercased, lowercased 20 | * 변경된 문자열이 새로 생성됨 21 | */ 22 | let uppercaseStr = str.uppercased() 23 | let lowercaseStr = str.lowercased() 24 | print(uppercaseStr, lowercaseStr) 25 | 26 | 27 | /* 28 | * 특정 위치에 문자 삽입 : insert() 29 | */ 30 | var helloStr = "Hello Wld" 31 | // 인덱스 구하기. endIndex에서 앞으로 이동 32 | let index8 = helloStr.index(helloStr.endIndex, offsetBy: -2) 33 | helloStr.insert(contentsOf: ["o", "r"], at: index8) 34 | //helloStr.insert(contentsOf:"or".characters, at: index8) // Hello World 35 | print("Insert Characters :", helloStr) 36 | 37 | /* 38 | * 특정 위치의 문자 삭제 : remove() 39 | */ 40 | var helloStr2 = "Hello, World!" 41 | // "Hello, World" 42 | helloStr2.remove(at: helloStr2.index(before: helloStr2.endIndex) ) 43 | print("Remove Last Character :",helloStr2) 44 | 45 | 46 | /* 47 | * 특정 범위내 문자열 삭제 : removeSubrange() 48 | */ 49 | let range = helloStr2.index(helloStr2.startIndex, offsetBy:5)... 50 | // "Hello" 51 | helloStr2.removeSubrange(range) 52 | print("Remove range : ",helloStr2) 53 | 54 | 55 | /* 56 | * 문자열을 분리 : split() 57 | */ 58 | let commaStr = "123,456,789" 59 | let splited = commaStr.split(separator: ",") 60 | print("Splited by comma :", splited) 61 | 62 | /* 63 | * 문자열 범위 교환 : replace() 64 | */ 65 | var replaceStr = "Hello iOS!" 66 | let replaceRangeStart = replaceStr.index(replaceStr.startIndex, offsetBy: 6) 67 | let replaceRangeEnd = replaceStr.index(replaceStr.endIndex, offsetBy: -2) 68 | 69 | replaceStr.replaceSubrange( replaceRangeStart...replaceRangeEnd, with: "Swift") 70 | print("replaced string :", replaceStr) // Hello Swift! 71 | -------------------------------------------------------------------------------- /02.Type/String_Substring.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 부분 문자열 3 | * Swift의 문자열(String)에서 문자 위치는 String.Index 타입을 사용한다. 4 | */ 5 | let str = "Hello Swift" 6 | 7 | // 문자열의 인덱스. String.Index 타입 8 | let startIndex: String.Index = str.startIndex 9 | 10 | // 문자열 인덱스를 이용해서 해당 문자(Character) 얻기 11 | let firstCharacter: Character = str[startIndex] 12 | 13 | print("첫번째 문자 \(firstCharacter)") 14 | 15 | 16 | // 에러 : endIndex를 바로 사용하면 범위를 벗어난다. -1 해서 사용 17 | let endIndex = str.endIndex 18 | //let endCharacter: Character = str[endIndex] 19 | 20 | // 인덱스 이동하기 index함수 사용 21 | let lastIndex = str.index(before: endIndex) 22 | let lastCharacter : Character = str[lastIndex] 23 | print("마지막 문자 : \(lastCharacter)") 24 | 25 | // 3번째 인덱스, 뒤에서 7번째 인덱스 얻기 26 | let index3 = str.index(str.startIndex, offsetBy: 3) 27 | let index7 = str.index(str.endIndex, offsetBy: -4, limitedBy: str.startIndex)! // 11-4 28 | print("3번째 문자 : \(str[index3]), 뒤에서 4번째 문자 : \(str[index7])") 29 | 30 | // 인덱스 범위 벗어나면 에러 31 | //let indexBound = str.index(str.endIndex, offsetBy:1) 32 | 33 | /* 34 | * 부분 문자열은 SubString 타입이다. 35 | */ 36 | 37 | // 범위 연산자를 이용한 부분 문자열얻기. 타입은 Substring 38 | let subStr1: Substring = str[startIndex...index3] // "Hell" 39 | print("Hello Swift[0...3]: ", subStr1) 40 | 41 | // ...str.endIndex로 사용하면 에러 발생 42 | let subStr2 = str[index7.. String 자동 타입 변환 안됨 52 | // let strFromSubstr2: String = subStr1 53 | 54 | let subStrAppend: Substring = subStr1 + subStr2 55 | -------------------------------------------------------------------------------- /02.Type/String_Views.swift: -------------------------------------------------------------------------------- 1 | // https://developer.apple.com/reference/swift/string 2 | 3 | let str = "I ♥ Swift" 4 | print("str : ", str) 5 | 6 | 7 | // Character의 집합(Collection) 8 | let charArray = Array(str) 9 | print("Character count :", charArray.count, " Character Array :", charArray) 10 | 11 | // UTF8 12 | let utf8Views : String.UTF8View = str.utf8 13 | let utf8Array = Array(utf8Views) 14 | print("UTF8 count :", utf8Array.count, " UTF8 Array :", utf8Array) 15 | 16 | // UTF16 17 | let utf16View : String.UTF16View = str.utf16 18 | let utf16Array = Array(utf16View) 19 | print("UTF16 count :", utf16Array.count, " UTF16 Array :", utf16Array) 20 | 21 | // UnicodeScalars 22 | let scalars = str.unicodeScalars 23 | let scalarsArray = Array(scalars) 24 | print(scalarsArray) 25 | 26 | print("=====") 27 | 28 | let str2 = "🐶‼" 29 | print("str2 : ", str2) 30 | 31 | let charArray2 = Array(str2) 32 | print("Character count :", charArray2.count, " Character Array :", charArray2) 33 | 34 | // UTF8 35 | let utf8Views2 : String.UTF8View = str2.utf8 36 | let utf8Array2 = Array(utf8Views2) 37 | print("UTF8 count :", utf8Array2.count, " UTF8 Array :", utf8Array2) 38 | 39 | // UTF16 40 | let utf16View2 : String.UTF16View = str2.utf16 41 | let utf16Array2 = Array(utf16View2) 42 | print("UTF16 count :", utf16Array2.count, " UTF16 Array :", utf16Array2) 43 | 44 | // UnicodeScalars 45 | let scalars2 = str2.unicodeScalars 46 | let scalarsArray2 = Array(scalars2) 47 | print(scalarsArray2) 48 | -------------------------------------------------------------------------------- /02.Type/TypeOf.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 타입 정보 얻기 ( type(of : arg) ) 3 | */ 4 | 5 | let str = "Hello World" 6 | print("String Type : \(type(of:str))") 7 | 8 | let value1 = 1234 9 | print("Int Type : \(type(of:value1))") 10 | 11 | let value2 = 3.14159 12 | print("Double Type : \(type(of:value2))") 13 | 14 | let intVal = 1 // 기본 Int 타입 15 | let int8Val : Int8 = 2 16 | let uintVal : UInt = 3 17 | 18 | // type(of:)를 이용한 타입 체크 19 | print("type(of: Int) == type(of: Int) :", type(of: intVal) == type(of: value1) ) 20 | print("type(of: Int) == type(of: UInt) :", type(of: intVal) == type(of: uintVal) ) 21 | 22 | // 타입 크기 23 | let intTypeInfo = type(of: intVal) 24 | print("Int BitWidth : ", intTypeInfo.bitWidth) 25 | 26 | let int8TypeInfo = type(of: int8Val) 27 | print("Int8 BitWidth : ", int8Val.bitWidth) 28 | 29 | // Type.self를 이용해서 타입 체크 30 | print("type(of: Int) == Int.Type :", type(of: intVal) == Int.self) 31 | print("type(of: Int) == String.Type :", type(of: intVal) == String.self) 32 | 33 | // is를 이용한 타입 체크 34 | print("Int value is Int :", intVal is Int) 35 | print("Int value is String :", intVal is String) 36 | 37 | -------------------------------------------------------------------------------- /02.Type/Unicode.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 유니코드와 문자 변환 3 | */ 4 | 5 | let ch : Character = "a" 6 | 7 | let scalar : Unicode.Scalar = ch.unicodeScalars.first! 8 | print("a unicode.scalar.value : ", scalar.value) // 97 9 | 10 | let ch2 : Character = "\u{61}" // 10진수 97 11 | print("61 : ",ch2) 12 | 13 | // Unicode 코드값에서 문자 얻기 14 | let heartScalar = Unicode.Scalar(0x2665)! 15 | let heartCharacter = Character(heartScalar) 16 | print("Unicode.Scalar(0x2665) ", heartCharacter) // ♥ 17 | -------------------------------------------------------------------------------- /03.CollectionType/Array.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 배열 생성 3 | // 4 | let intArray = [1, 2, 3, 4, 5] 5 | let strArray : [String] = ["A", "B", "C"] 6 | let floatArray = Array([1.1, 2.2, 3.3]) 7 | 8 | // 빈 배열 생성 9 | var emptyArray : [Int] = [] 10 | var emptyArray2 = [Double]() 11 | var emtpyArray3 = Array() 12 | 13 | print("intArray : ",intArray) 14 | // 원소 갯수 15 | print("intArray : count : ", intArray.count) 16 | print("emptyArray isEmpty : ",emptyArray.count) 17 | // 빈 배열 확인 18 | print("intArray isEmpty : ",intArray.isEmpty) 19 | print("emptyArray isEmpty : ",emptyArray.isEmpty) 20 | 21 | // 22 | // 배열 내용 접근 23 | // 24 | let element1 = intArray[0] // 1 25 | let element2 = floatArray[1] // 2.2 26 | let element3 = floatArray.first 27 | let element4 = strArray.last 28 | // 원소 접근 에러 - fatal error: Index out of range 29 | // let element5 = strArray[3] 30 | 31 | // 원소 포함 여부 32 | print("intArray contains(3): ", intArray.contains(3)) 33 | print("intArray contains(6): ", intArray.contains(6)) 34 | 35 | /* 36 | * 배열 수정 37 | */ 38 | 39 | // 배열 수정은 var로 선언해야 가능. let으로 선언한 배열은 수정 불가 40 | var editableArray : [Int] = [1, 2, 3] 41 | 42 | // 원소를 배열 끝에 추가 43 | editableArray.append(5) // [1, 2, 3, 5] 44 | // 원소를 배열 중간에 추가 45 | editableArray.insert(4, at: 3) // [1, 2, 3, 4, 5] 46 | 47 | // + 연산자를 이용해서 배열 덧붙이기 48 | let appendedArray = editableArray + [6] // [1, 2, 3, 4, 5, 6] 49 | print("appendedArray:",appendedArray) 50 | // += 연산자를 이용해서 원래 배열에 덧붙이기 51 | editableArray += [6, 7] // [1, 2, 3, 4, 5, 6, 7] 52 | 53 | // 54 | // 삭제하기 55 | // 56 | editableArray.removeLast() // 7 57 | print("After removeLast : ",editableArray) // [1, 2, 3, 4, 5, 6] 58 | 59 | // index 2 원소 지우기 60 | editableArray.remove(at:2) // 3 61 | print("After removeAtIndex(2) : ", editableArray) // [1, 2, 4, 5, 6] 62 | 63 | print("intArray : ", editableArray) // [1, 2, 4, 5, 6] 64 | print("intArray[3] : ", editableArray[3]) // 5 65 | editableArray[2] = 3 66 | print("intArray : ", editableArray) // [1, 2, 3, 5, 6] 67 | 68 | editableArray[3..<5] = [4, 5, 6] 69 | print("After [3..<5] = = [4, 5, 6] : ", intArray) // [1, 2, 3, 4, 5, 6] 70 | 71 | 72 | -------------------------------------------------------------------------------- /03.CollectionType/ComplexCollection.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 복합 구조 3 | */ 4 | 5 | // 2차원 배열 6 | // [[String]], Array<[String]>, Array> 7 | // Any를 사용해서 [Any] 도 가능. 8 | var twoDimensionArray : [[String]] = [["a", "b"], ["c", "d", "e"], ["f"]] 9 | let itemArray : [String] = twoDimensionArray[1]; // ["c", "d", "e"] 10 | let itme : String = twoDimensionArray[1][2]; // "d" 11 | print(itemArray) 12 | print(twoDimensionArray[1][1]) 13 | 14 | 15 | // 배열과 딕셔너리 혼합 16 | // 17 | // [String, [Int]] 혹은 Dictionary 18 | // Any를 사용해서 [String, Any] 타입으로 선언 가능 19 | let evenNums = [2, 4, 6] 20 | let oddNums = [1, 3, 5, 7] 21 | let dic : [String:[Int]] = ["even" : evenNums, "odd" : oddNums] // Dictionary, [String, Any] 22 | 23 | let oddNumbers = dic["odd"]! // [1, 3, 5, 7] 24 | let oddNum = oddNumbers[2] // 5 25 | print(oddNumbers) 26 | print(oddNum) -------------------------------------------------------------------------------- /03.CollectionType/Dictionary.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 딕셔너리 타입 3 | */ 4 | 5 | 6 | // 딕셔너리 만들기 7 | // 타입 선언 생략 8 | var dic = ["1월":"January", "2월":"February", "3월":"March"] 9 | // Dictionary 객체 생성 10 | var dic2 : Dictionary = [1 : "One", 2 : "Two", 3 : "Three"] 11 | // Shorthand 12 | var dic3 : [String: Int] = ["일" : 1, "이" : 2, "삼" : 3] 13 | // 빈 Dictionary 객체 14 | var emptyDic = [Int: Int]() 15 | 16 | // 딕셔너리 원소의 개수 17 | print("dic.count : ", dic.count) 18 | print("emptyDic.count : ", emptyDic.count) 19 | 20 | // 딕셔너리의 값 접근하기 21 | let value1 = dic["1월"]! 22 | print("dic[1월] : ", value1) // "January" 23 | // 딕셔너리에 없는 키로 접근하면 nil이 반환된다. 24 | let value2 = dic3["사"] 25 | print("dic[사] : ", value2) // nil 26 | 27 | // 딕셔너리에 없는 키로 접근했을 때 nil대신 출력될 값에 해당하는 키를 입력. 28 | let value3 = dic["사", default: "일"] 29 | print("dic[사, defualt:일] : ", value3) 30 | 31 | // 주의 : 딕셔너리의 키가 Int명 배열처럼 보일 수도 있다. 32 | let value4 = dic2[1]! 33 | print("dic2[1] : ", value4) // "One" 34 | 35 | 36 | // 딕셔너리에 값 설정/수정하기 37 | 38 | dic["4월"] = "april" 39 | dic["5월"] = "May" 40 | 41 | dic["4월"] = "잔인한 달" 42 | dic.updateValue("계절의 여왕", forKey: "5월") 43 | 44 | print("dic : ", dic) 45 | 46 | dic.removeValue(forKey:"2월") 47 | dic["3월"] = nil 48 | print("dic[3월] = nil : ", dic) 49 | -------------------------------------------------------------------------------- /03.CollectionType/Set.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Set 타입 예제 3 | * swift2 4 | */ 5 | 6 | var beverage : Set = ["Coke", "Juice", "Milk"] 7 | var intSet : Set = [1, 2, 3, 4, 5] 8 | 9 | // 공백의 셋 객체 생성 10 | var letters = Set() 11 | 12 | 13 | beverage.insert("Soda") 14 | beverage.remove("Milk") 15 | 16 | 17 | print("beverage : ", beverage) // {"Juice", "soda", "Coke"} 18 | print("beverage.count : ", beverage.count) // 3 19 | print("beverage.contains(Coke) : ", beverage.contains("Coke")) 20 | print("beverage.contains(Sprite) : ", beverage.contains("Sprite")) 21 | 22 | print("beverage.first : ", beverage.first) 23 | 24 | /* 25 | * Set 타입 예제 26 | */ 27 | 28 | var primeNumbers : Set = [1, 2, 3, 5, 7, 11, 13] 29 | var oddNumbers : Set = [1, 3, 5, 7, 9] 30 | 31 | // 교집합 32 | // intersection : Immutable API 33 | // formIntersection : Mutable API 34 | print("교집합 : ", primeNumbers.intersection(oddNumbers)) // 교집합 [1, 3, 5, 7] 35 | 36 | // 합집합 37 | // union : Immutable API 38 | // formUnion : Mutable API 39 | print("합집합 : ", primeNumbers.union(oddNumbers)) // 합집합 [1, 2, 3, 5, 7, 9, 11, 13] 40 | 41 | // 여집합 구하기 42 | // symmetricDifference : Immutable API 43 | // formSymmetricDifference : Mutable API 44 | print("여집합 : ", primeNumbers.symmetricDifference(oddNumbers)) // 여집합 [2, 9, 11, 13] 45 | 46 | // 차집합 구하기 47 | // subtracting : Immutable API 48 | // subtract : Mutable API 49 | print("차집합 : ", primeNumbers.subtracting(oddNumbers)) // 차집합 [2, 11, 13] 50 | -------------------------------------------------------------------------------- /03.CollectionType/Tuple.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 튜플(Tuple) 3 | // 4 | 5 | // 튜플 선언. 타입 생략 가능 6 | var one = (1, "one", "일") 7 | // 튜플 타입 선언 8 | let two: (Int, String, String) = (num : 2, eng : "two", kor : "둘") 9 | 10 | // 투플 원소에 접근해서 값 얻기/변경 11 | print(one.2) 12 | one.2 = "하나" 13 | 14 | print("one : ", one) 15 | 16 | // 튜플 원소에 이름 설정 17 | let three: (num: Int, eng: String, kor: String) = (num : 2, eng : "two", kor : "둘") 18 | 19 | print("num : \(three.num), kor : \(three.kor)") 20 | 21 | // 투플 간 비교 22 | print("(1,1) == (1,1) : ",(1, "1") == (1, "1")) 23 | print("(1, one) < (2, two) : ", (1, "one") < (2, "two")) 24 | print("(1, one) < (1, first)", (1, "one") < (1, "first")) 25 | 26 | // 새로운 튜플에 값 대입 - 복사된다. 27 | var sam = three 28 | sam.eng = "Third" 29 | sam.kor = "세번째" 30 | 31 | // 튜플 원소 대입 32 | let (two1, two2, two3) = two 33 | print("튜플(two)의 두 번째 원소 :", two2) 34 | 35 | // 튜플 원소 중 일부만 대입 36 | let (_, engOne, _) = one 37 | print("튜플(one)의 두 번째 원소 :", engOne) 38 | -------------------------------------------------------------------------------- /03.CollectionType/ValueType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 밸류 타입. 배열, 딕셔너리, 셋은 모두 밸류 타입 3 | // 4 | 5 | var array1 : [Int] = [1, 2, 3] 6 | 7 | // 새로운 변수/상수에 대입하면 복사된다. 8 | var array2 = array1 9 | 10 | if array1 == array2 { 11 | print("같은 값의 원소 배열") 12 | } 13 | 14 | // 배열 중 하나만 변경 15 | array1.append(4) 16 | 17 | 18 | // 서로 값이 다르다. 19 | print("array1 : ", array1) // [1, 2, 3, 4] 20 | print("array2 : ", array2) // [1, 2, 3] -------------------------------------------------------------------------------- /04.Controls/for.swift: -------------------------------------------------------------------------------- 1 | // For Loop 2 | let limit = 3 3 | 4 | // 범위를 사용하는 For Loop. C 스타일 for 문은 삭제 5 | for i in 0.. 0 else { 18 | print("item의 값이 0보다 크지 않다.") 19 | break 20 | } 21 | print(item) 22 | } 23 | 24 | -------------------------------------------------------------------------------- /04.Controls/if.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Basic 3 | // 4 | if 3 > 2 { 5 | print("3이 2보다 크다!") 6 | } 7 | 8 | 9 | // 10 | // nil 비교 11 | // 12 | var obj : String! 13 | 14 | if obj != nil { 15 | print("obj에 유요한 값") 16 | } 17 | 18 | // 19 | // if - else if - else 20 | // 21 | var bloodType = "C" 22 | if bloodType == "A" { 23 | print("혈액형은 A") 24 | } 25 | else if bloodType == "B" || bloodType == "O" { 26 | print("B나 O형") 27 | } 28 | else { 29 | print("그러면 AB형") 30 | } 31 | -------------------------------------------------------------------------------- /04.Controls/label.swift: -------------------------------------------------------------------------------- 1 | // 2 | // label 3 | // 4 | let lower = "abcdef" 5 | let upper = "ABCDEF" 6 | 7 | 8 | print("== Without Label") 9 | 10 | for i in 0...5 { 11 | for j in lower { 12 | for k in upper { 13 | if k == "C" { 14 | break 15 | } 16 | print(i,j,k) 17 | } 18 | } 19 | } 20 | 21 | print("== With Label") 22 | 23 | loop1 : for i in 0...5 { 24 | loop2 : for j in lower { 25 | for k in upper { 26 | if k == "C" { 27 | break loop2 28 | } 29 | print(i,j,k) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /04.Controls/switch_case.swift: -------------------------------------------------------------------------------- 1 | var someValue = 3 2 | switch someValue { 3 | case 1: 4 | print("1") 5 | // 모든 가능한 경우를 비교하는 case가 없으면 default 필수 6 | default: 7 | print("Other") 8 | } 9 | 10 | switch someValue { 11 | case 1, 2, 3: 12 | print("1, 2 혹은 3") 13 | fallthrough // 이후 case실행 14 | case 4 ..< 6: 15 | print("4에서 5사이") 16 | case 6: 17 | print("Six") 18 | default: 19 | print("나머지.") 20 | } 21 | 22 | // String 23 | var str = "Morning" 24 | switch str { 25 | case "Morning": 26 | print("Good Morning") 27 | case "Afternoon": 28 | print("Good Afternoon") 29 | case "Evening": 30 | print("Good Evening") 31 | default: 32 | print("Bye Bye") 33 | } 34 | 35 | // 튜플 36 | var tupleVal = (1, "One") 37 | switch tupleVal { 38 | case (0, "Zero"): 39 | print("0, zero") 40 | case (0, "영"): 41 | print("0, 영") 42 | case (1, _): 43 | print("1, 일") 44 | default: 45 | print("Other)") 46 | } 47 | 48 | // Value binding 49 | var point = (2, 2) 50 | switch point { 51 | case (1, let y): 52 | print("1, \(y)") 53 | case (let x, 2) : 54 | print("\(x), 2") 55 | case let(x, y): 56 | print("\(x), \(y)") 57 | } 58 | 59 | // Value binding and where 60 | switch point { 61 | case let(x, y) where x > 0: 62 | print("x가 0보다 크다") 63 | case let(x, y) where x < 0 && y > 0: 64 | print("2사 분변") 65 | default: 66 | print("그 외") 67 | } -------------------------------------------------------------------------------- /04.Controls/version-check.swift: -------------------------------------------------------------------------------- 1 | func versionTest() { 2 | if #available(iOS 9, *) { 3 | print("iOS9 이상") 4 | } 5 | 6 | if #available(macOS 10.12, *) { 7 | print("macOS 10.12 이상") 8 | } 9 | else { 10 | print("macOS 10.12 아래") 11 | } 12 | 13 | guard #available(iOS 10, macOS 10.12, tvOS 10, watchOS 3, *) else { 14 | print("최신 버전이 아님") 15 | return 16 | } 17 | 18 | print("최신 버전") 19 | } 20 | 21 | versionTest() -------------------------------------------------------------------------------- /04.Controls/while.swift: -------------------------------------------------------------------------------- 1 | let count = 3 2 | 3 | var i = 0 4 | while i < count { 5 | print("i = \(i)") 6 | i += 1 // i++ 은 deprecated 7 | } 8 | 9 | // Do-While 대신 10 | var j = 0 11 | repeat { 12 | print("j = \(j)") 13 | j += 1 // j++ 은 deprecated 14 | if j > count { 15 | break // break 로 반복 작업 끝내기 16 | } 17 | } while true 18 | -------------------------------------------------------------------------------- /05.Optional/ForcedUnwrapping.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 강제 언래핑 3 | */ 4 | 5 | var optionalVal: Int? = 1 6 | let unwrappedVal: Int = optionalVal! 7 | print(unwrappedVal + 1) 8 | 9 | optionalVal = nil 10 | // nil인 상황에서 강제 언래핑 - 런타임 에러 발생 11 | //let unwrappedVal2 = optionalVal! 12 | 13 | let intVal1: Int? = Int("1") // Int? 14 | print(intVal1) 15 | 16 | let intVal2: Int = Int("1")! // Int 타입 17 | print(intVal2) 18 | 19 | let intVal3 = Int("A") // nil 20 | print(intVal3) 21 | //let intVal4 = Int("A")! // Error 22 | 23 | let dictionary = ["one":1, "two":2] 24 | let two: Int = dictionary["two"]! // non-optional Int 타입 25 | print("two in Dictionary : ", two) 26 | 27 | //let three = dictionary["three"]! // Error 28 | -------------------------------------------------------------------------------- /05.Optional/IUO.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 암시적 언래핑 옵셔널 타입(IUO, Implicit Unwrapping Optional) 3 | // 4 | 5 | var iuoVal : Int! = 123 6 | 7 | // nil로 초기화된다. 8 | var iuoStr : String! 9 | if iuoStr == nil { 10 | print("IUO는 nil로 초기화") 11 | } 12 | 13 | let advVal = iuoVal.advanced(by: 4) // !나 ? 기호 없이 사용 14 | print(advVal) // 127, 옵셔널 타입이 아니다. 15 | 16 | // IUO 타입은 nil 대입 가능 17 | iuoVal = nil 18 | // fatal error: unexpectedly found nil while unwrapping an Optional value 19 | // let advVal2 = iuoVal.advanced(by: 1) // Error 20 | 21 | 22 | // 배열과 IUO 23 | let iuoArray : [String]! = ["1", "2", "3"] 24 | let item = iuoArray[1] // String 타입. !나 ? 기호 없이 배열의 원소 접근 -------------------------------------------------------------------------------- /05.Optional/NilCheck.swift: -------------------------------------------------------------------------------- 1 | var optionalVar : Int? = nil 2 | 3 | // 아래의 방법으로 nil 검사는 불가능하다. 4 | //if optionalVar { 5 | // print("유효한 값이다.") 6 | //} 7 | 8 | if optionalVar == nil { 9 | print("nil 이다") 10 | } 11 | 12 | 13 | optionalVar = 99 14 | if optionalVar != nil { 15 | print("유효한 값이다") 16 | } 17 | -------------------------------------------------------------------------------- /05.Optional/NilCoalescing.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * nil 병합 연산지 3 | */ 4 | 5 | var userSelectedColor : String? 6 | // nil 이면 Red를 사용 7 | var colorName: String = userSelectedColor ?? "Red" 8 | 9 | print(colorName) // "Red 10 | -------------------------------------------------------------------------------- /05.Optional/Optional.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Optional, nil 예제 3 | */ 4 | 5 | // Error 6 | // var i : Int = nil 7 | // Optional Type 8 | 9 | var optionalVar : Int? = nil 10 | var optionalVar2 : Optional = nil 11 | 12 | print("nil 대입된 변수 : ",optionalVar, optionalVar2) 13 | 14 | // 타입 변환시 발생하는 nil 15 | let intFromStr = Int("a") // Int? 타입 16 | print("int from string : ", intFromStr) 17 | 18 | // 딕셔너리 원소 접근 19 | let numbers = ["one":1, "two":2] 20 | let three = numbers["three"] // Int? 21 | print("three from dictionary : ", three) 22 | 23 | 24 | /** 25 | * 옵셔널 타입의 값을 사용하기 - 언래핑 필요 26 | */ 27 | 28 | var optionalNumber: Int? = 10 29 | // 컴파일 에러 30 | // let ret = optionalNumber + 1 31 | -------------------------------------------------------------------------------- /05.Optional/OptionalBinding.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Optional Binding 예제 3 | */ 4 | // 5 | // if - binding 6 | // 7 | var nilAvailable : Int? = 99 8 | 9 | if let val = nilAvailable { 10 | print("nilAvailable은 유효한 값 : \(val)") // val은 non-optional 11 | } 12 | 13 | nilAvailable = nil 14 | if let val = nilAvailable { 15 | print("유효한 값 : \(val)") // val은 non-optional 16 | } 17 | else { 18 | print("nilAvailable은 nil이다.") 19 | } 20 | 21 | func someFunc() -> Int? { 22 | return 1 23 | } 24 | 25 | func anotherFunc() -> Int? { 26 | return 0 27 | } 28 | 29 | if let val1 = someFunc(), let val2 = anotherFunc() { 30 | print("val1, val2는 모두 유효한 값") 31 | } 32 | 33 | // 34 | // Optional binding and condition 35 | // 36 | let condition = true 37 | 38 | if let val = someFunc(), condition == true { 39 | print("val은 유효한 값이고 condition은 true다.") 40 | } 41 | 42 | if let val = anotherFunc(), val > 0 { 43 | print("anotherFunc의 결과는 유효하고, 0보다 크다 ") 44 | } 45 | 46 | // 47 | // if - binding. chain 48 | // 49 | 50 | let nilAvailableStr : String? = "123" // "abc", nil 51 | if let val1 = nilAvailableStr, let val2 = Int(val1) { 52 | print("nilAvailableStr는 유효한 값이고, Int 타입으로 변환하면 : \(val2)다.") 53 | } 54 | 55 | 56 | // 57 | // guard를 사용한 옵셔널 바인딩 58 | // 59 | 60 | func doIt(_ arg: Int?) { 61 | guard let val = arg else { 62 | print("입력값은 nil") 63 | return; 64 | } 65 | 66 | // val 에 접근하기 67 | print("입력값은 유효한 값 : \(val)") 68 | } 69 | doIt(1) 70 | doIt(nil) 71 | 72 | func bindingWithCondition() { 73 | guard let val = nilAvailable, val > 0 else { 74 | return; 75 | } 76 | print("val은 유효하고 0보다 큰 값이다. \(val)") 77 | } 78 | bindingWithCondition() 79 | 80 | // 81 | // guard - biding-chain 82 | // 83 | 84 | func bindingChain() { 85 | let nilAvailableStr : String? = "123" // "abc", nil 86 | 87 | guard let val1 = nilAvailableStr, let val2 = Int(val1) else { 88 | print("nilAvailableStr는 유효하지 않거나 Int로 변환할 수 없다.") 89 | return; 90 | } 91 | 92 | print("nilAvailableStr는 유효한 값이고, Int 타입으로 변환하면 : \(val2)다.") 93 | } 94 | bindingChain() -------------------------------------------------------------------------------- /05.Optional/OptionalChain.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 옵셔널 체인 3 | // 4 | 5 | var optionalStr : String? = "ABC" 6 | 7 | let str = optionalStr?.lowercased() // str은 옵셔널 타입. Optional("abc") 8 | print(str) 9 | 10 | 11 | optionalStr = nil 12 | let str2 = optionalStr?.lowercased() // nil 13 | print(str2) 14 | 15 | 16 | let array : [String]? = ["A", "B", "C"] 17 | let str3 = array?[1].lowercased() 18 | print(str3) 19 | 20 | 21 | // ?? 연산자 22 | var userSelectedColor : String? 23 | var colorName = userSelectedColor ?? "Red" // nil 이면 Red를 사용 24 | print(colorName) // "Red" 25 | 26 | 27 | 28 | // 29 | // 옵셔널 체인에 강제 언래핑 사용 30 | // 31 | optionalStr = "ABC" 32 | let str1 = optionalStr!.lowercased() // str1은 논옵셔널 타입. 33 | print(str1) 34 | 35 | optionalStr = nil 36 | //let str2 = optionalStr!.lowercased() // Error 37 | -------------------------------------------------------------------------------- /06.CustomType/Class.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * class 정의와 객체 생성 3 | */ 4 | 5 | class Person { 6 | var name : String = "" 7 | var age : Int = 0 8 | } 9 | 10 | let tarantino = Person() 11 | tarantino.name = "Quentin Jerome Tarantino" 12 | 13 | print(tarantino.name) 14 | 15 | 16 | class Drink { 17 | var name: String? 18 | var price: Int? 19 | } 20 | 21 | 22 | class Unit { 23 | var life = 0 24 | } 25 | 26 | class MovingUnit : Unit { 27 | var x = 0 28 | var y = 0 29 | } 30 | 31 | let scv = MovingUnit() 32 | scv.life = 100 33 | scv.x = 10 34 | scv.y = 20 -------------------------------------------------------------------------------- /06.CustomType/ComplexType.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 커스텀 타입의 조합 3 | */ 4 | 5 | class Music { 6 | var title: String? 7 | var artist: String? 8 | } 9 | 10 | class Theater { 11 | var name: String? 12 | var location: String? 13 | } 14 | 15 | enum Genre { 16 | case sf, drama, action, other 17 | } 18 | 19 | struct Movie { 20 | var title: String 21 | var ost: Music 22 | var theaters: [Theater] 23 | var genre: Genre 24 | } 25 | -------------------------------------------------------------------------------- /06.CustomType/Enum.swift: -------------------------------------------------------------------------------- 1 | enum Day { 2 | case am 3 | case pm 4 | } 5 | 6 | var now : Day 7 | now = Day.am 8 | 9 | switch now { 10 | case .am: 11 | print("오전") 12 | case .pm: 13 | print("오후") 14 | } 15 | 16 | // RawValue 17 | 18 | enum Pet : String { 19 | case cat = "고양이" 20 | case dog = "개" 21 | case other = "그외" 22 | } 23 | 24 | // rawValue에서 enum얻기 25 | var ael: Pet? = Pet(rawValue:"고양이") 26 | print(ael) 27 | 28 | // enum에서 rawValue 얻기 29 | var raz: Pet = Pet.cat 30 | let razRawValue: String = raz.rawValue 31 | print("Pet.cat : rawValue : ", razRawValue) // 고양이 32 | -------------------------------------------------------------------------------- /06.CustomType/Struct.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Struct 정의와 객체 생성 3 | */ 4 | 5 | struct Movie { 6 | var title : String 7 | var year : Int 8 | } 9 | 10 | let avata = Movie(title: "아바타", year: 2009) 11 | print(avata.title) 12 | 13 | var avengers = Movie(title: "어밴져스", year: 0) 14 | avengers.year = 2012 15 | 16 | print(avengers.title) 17 | 18 | var movies: [Movie] = [] 19 | 20 | movies.append(avata) 21 | movies.append(avengers) 22 | 23 | 24 | struct Song { 25 | var title: String 26 | var artist: String 27 | var image: String? 28 | } 29 | 30 | 31 | let song = Song(title: "좋은날", artist: "IU", image: nil) 32 | 33 | struct Book { 34 | var title: String 35 | var sales = 0 36 | } 37 | 38 | 39 | struct Bird { 40 | var name: String 41 | static let species = "새" 42 | } 43 | 44 | print(Bird.species) 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /06.CustomType/Typealias.swift: -------------------------------------------------------------------------------- 1 | typealias Century = Int 2 | 3 | var thisEra : Century 4 | thisEra = 21 5 | 6 | print(thisEra) 7 | -------------------------------------------------------------------------------- /06.CustomType/ValueAndReferenceType.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 클래스(레퍼런스 타입)과 구조체(밸류 타입) 비교 3 | */ 4 | 5 | class MyClass { 6 | var value = 0 7 | } 8 | 9 | var obj1 = MyClass() 10 | var obj2 = obj1 11 | 12 | obj1.value = 10 13 | print(obj2.value) // 10 14 | 15 | 16 | 17 | struct MyStruct { 18 | var value = 0 19 | } 20 | 21 | var obj3 = MyStruct() 22 | var obj4 = obj3 // 객체 복사 23 | 24 | obj3.value = 10 25 | print(obj4.value) // 0 26 | 27 | 28 | var array1 = [1, 2, 3] 29 | var array2 = array1 // 복사 30 | 31 | // 하나의 배열의 값 변경 32 | array1.append(4) 33 | 34 | print(array1) // [1,2,3,4] 35 | print(array2) // [1,2,3] 36 | 37 | -------------------------------------------------------------------------------- /07.Function/Function.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // 함수 정의 4 | func greeting() { 5 | print("Hello Swift") 6 | } 7 | 8 | // 함수 실행 9 | greeting() 10 | 11 | // Void, () 반환타입. 생략 가능 12 | func greeting2() -> Void { 13 | print("Hello Swift!") 14 | } 15 | greeting2() 16 | 17 | 18 | // Bool 반환 19 | func areYouOK() -> Bool { 20 | return true 21 | } 22 | let ok = areYouOK() // true 23 | 24 | // 문자열 반환 25 | func favoriteDrink() -> String { 26 | return "Coffee" 27 | } 28 | let drink = favoriteDrink() // "Coffee" 29 | 30 | 31 | func random3() -> (Int, Int, Int) { 32 | // 난수값 생성 함수 : arc4random. Foundation 프레임워크 필요 33 | let r1 = Int(arc4random() % 10) 34 | let r2 = Int(arc4random() % 10) 35 | let r3 = Int(arc4random() % 10) 36 | 37 | return (r1, r2, r3) 38 | } 39 | 40 | var nums = random3() 41 | print("Random Numbers2 : \(nums.0), \(nums.1), \(nums.2)") 42 | 43 | var (num1, num2, num3) = random3() 44 | print("Random Numbers : \(num1), \(num2), \(num3)") 45 | -------------------------------------------------------------------------------- /07.Function/NestedFunction.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 함수 내부에 함수 정의하기 3 | */ 4 | 5 | func outerFunc() { 6 | func innerFunc() { 7 | print("Inner Function works") 8 | } 9 | 10 | print("Outer Function works") 11 | 12 | innerFunc() 13 | } 14 | 15 | 16 | outerFunc() 17 | 18 | // Error - 내부에 정의된 함수 접근 불가 19 | //innerFunc() // Error 20 | -------------------------------------------------------------------------------- /07.Function/OptionalParamReturn.swift: -------------------------------------------------------------------------------- 1 | func sayHello(who : String) { 2 | print("Hello \(who)") 3 | } 4 | 5 | // Error 6 | //sayHello(who: nil) 7 | 8 | 9 | // nil이 반환될 수도 있는 함수 10 | func nilReturnFunction() -> Int? { 11 | return nil 12 | } 13 | 14 | let ret = nilReturnFunction() 15 | 16 | // 함수 실행 결과를 이용한 옵셔널 바인딩 17 | if let ret = nilReturnFunction() { 18 | print("실행 결과 : \(ret)") 19 | } 20 | 21 | 22 | func append(str : String, int val : Int?) -> String { 23 | // guard를 이용한 파라미터 nil 검사. 24 | guard let num = val else { 25 | return str 26 | } 27 | 28 | return str + String(num) 29 | } 30 | 31 | let ret1 = append(str: "Hello", int: 1) 32 | print(ret1) 33 | 34 | // nil을 파라미터로 입력 35 | let ret2 = append(str: "Welcome", int: nil) 36 | print(ret2) 37 | 38 | 39 | let iuoVal : Int! = 3 40 | let ret3 = append(str: "Bye", int: iuoVal) 41 | print(ret3) 42 | 43 | 44 | 45 | func areYouReady() -> Bool! { 46 | return nil 47 | } 48 | 49 | let ready : Bool! = areYouReady() 50 | print("ready? \(ready)") 51 | -------------------------------------------------------------------------------- /07.Function/Overloading.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Overroading 3 | // 4 | 5 | func sayHello(msg : String) { 6 | print("sayHello(msg:)") 7 | } 8 | 9 | func sayHello(_ msg : String) { 10 | print("sayHello(_:)") 11 | } 12 | 13 | func sayHello(_ times : Int) { 14 | print("sayHello(_:). Int type argument") 15 | } 16 | 17 | sayHello("msg") 18 | sayHello(msg : "msg") 19 | sayHello(10) 20 | 21 | -------------------------------------------------------------------------------- /07.Function/Parameter.swift: -------------------------------------------------------------------------------- 1 | // 파라미터가 1개인 함수 정의 2 | func greeting(person : String) { 3 | print("Hello " + person) 4 | } 5 | 6 | greeting(person: "Friend") 7 | 8 | // 파라미터가 2개인 함수 정의. 9 | func greeting(person : String, emotion:String) { 10 | print("Hello " + person + " with " + emotion) 11 | } 12 | 13 | greeting(person:"My Friend", emotion: "Smile") 14 | 15 | 16 | // 첫 번째 파라미터에 외부 파라미터 이름 설정 17 | func greeting(who person : String) { 18 | print("Hello " + person) 19 | } 20 | 21 | greeting(who: "Swift") 22 | 23 | 24 | // 두 번째 파라미터에 외부 파라미터 정의 25 | func greeting(person : String, with emotion : String) { 26 | print("Hello " + person + " with " + emotion) 27 | } 28 | 29 | greeting(person: "My Friend", with: "Hug") 30 | 31 | 32 | // 외부 파라미터 생략하기 33 | func greeting(_ person : String) { 34 | print("Hello " + person) 35 | } 36 | 37 | greeting("Friend") 38 | 39 | func greeting(person : String, _ emotion : String) { 40 | print("Hello " + person + " with " + emotion) 41 | } 42 | 43 | greeting(person: "Swift", "Passion") -------------------------------------------------------------------------------- /07.Function/ParameterDefaultValue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 기본값을 가진 파라미터 3 | // 4 | 5 | func greeting(person : String = "Friend") { 6 | print("Hello \(person)") 7 | } 8 | 9 | greeting(person: "Mom") 10 | greeting() // 파라미터 생략 11 | 12 | 13 | // Default Parameter가 2개 14 | func exercise(what : String, who : String = "Alone", emotion : String = "Joy") { 15 | print("\(what) \(who) \(emotion)") 16 | } 17 | 18 | exercise(what: "Jog") 19 | exercise(what: "Tennis", who: "Coach") 20 | exercise(what: "Dance", who: "Partnet", emotion: "fun") 21 | 22 | 23 | // Default Paramter w/o name 24 | 25 | func drive(_ to : String = "River", _ with : String = "Friend") { 26 | print("Drive \(to) \(with)") 27 | } 28 | 29 | drive() // Drive River Friend 30 | drive("Ocean") // Drive River Friend 31 | drive("Mountain", "Brother") // Drive Mountain Brother 32 | 33 | 34 | // 35 | // ambiguous. No error occur in Swift3 36 | // 37 | 38 | func sayHello() { 39 | print("Hello Swift!") 40 | } 41 | 42 | func sayHello(person : String = "Friend") { 43 | print("Hello \(person)") 44 | } 45 | 46 | 47 | func sayHello(person : String, msg : String = "How are you") { 48 | print("\(msg) \(person)") 49 | } 50 | 51 | sayHello() 52 | sayHello(person: "Mom") 53 | sayHello(person: "Friend", msg: "Good morning") 54 | -------------------------------------------------------------------------------- /07.Function/ParameterInout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // inout 파라미터 3 | // 4 | 5 | // 파라미터는 상수(let)으로 동작한다. 6 | func tryParameterChange(_ arg : Int) { 7 | // arg = arg + 1 // Error 8 | } 9 | 10 | tryParameterChange(10) 11 | 12 | 13 | // inout 으로 선언한 파라미터. 14 | func swapTwoValue(_ arg1 : inout Int, _ arg2 : inout Int) { 15 | let temp = arg1 16 | arg1 = arg2 17 | arg2 = temp 18 | } 19 | 20 | var value1 = 1 21 | var value2 = 2 22 | 23 | swapTwoValue(&value1, &value2) 24 | 25 | print("value1 :", value1) // 2 26 | print("value2 :", value2) // 1 27 | -------------------------------------------------------------------------------- /07.Function/ParameterVaridic.swift: -------------------------------------------------------------------------------- 1 | // 가변 길이 파라미터 2 | func addAll(_ values : Int...) -> Int { 3 | if values.count == 0 { 4 | return 0 5 | } 6 | else { 7 | var result = 0 8 | for v in values { 9 | result += v 10 | } 11 | return result 12 | } 13 | } 14 | 15 | let ret1 = addAll() 16 | print("ret1:", ret1) 17 | 18 | let ret2 = addAll(1) 19 | print("ret2:", ret2) 20 | 21 | let ret3 = addAll(1, 2, 3) // 6 22 | print("ret3:", ret3) -------------------------------------------------------------------------------- /08.StructAndEnum/EnumAndAssociation.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Enum, Association 3 | */ 4 | 5 | enum ArrivalStatus { 6 | case onTime 7 | case delay(Int) 8 | } 9 | 10 | var flight = ArrivalStatus.delay(1) 11 | 12 | switch flight { 13 | case .onTime: 14 | print("제때 도착") 15 | case .delay(let hour): 16 | print("지연 시각 \(hour)") 17 | } 18 | -------------------------------------------------------------------------------- /08.StructAndEnum/EnumAndMethod.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Enum에 프로퍼티와 메소드 작성 3 | */ 4 | 5 | enum Pet : Int { 6 | case cat = 0, dog, other 7 | 8 | var name : String { 9 | switch self { 10 | case .cat: 11 | return "고양이" 12 | case .dog: 13 | return "강아지" 14 | default: 15 | return "기타" 16 | } 17 | } 18 | 19 | func description() -> String { 20 | return self.name 21 | } 22 | } 23 | 24 | // 프로퍼티와 메소드 사용 25 | var raz = Pet.cat 26 | print(raz.name) 27 | print(raz.description()) 28 | -------------------------------------------------------------------------------- /08.StructAndEnum/ImmutableAndMutable.swift: -------------------------------------------------------------------------------- 1 | var array = [1, 3, 2, 4, 5] 2 | let sortedArray = array.sorted() 3 | print(sortedArray) 4 | print(array) 5 | 6 | array.sort() 7 | print(array) 8 | -------------------------------------------------------------------------------- /08.StructAndEnum/NestedType.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 타입 내장 3 | */ 4 | 5 | struct Rectangle { 6 | struct Point { 7 | var x, y : Int 8 | } 9 | 10 | struct Size { 11 | var width, height : Int 12 | } 13 | 14 | var origin : Point 15 | var size : Size 16 | 17 | init(origin : Point, size : Size) { 18 | self.origin = origin 19 | self.size = size 20 | } 21 | } 22 | 23 | let point = Rectangle.Point(x: 10, y: 10) 24 | print("Rectangle.Point : ", point) 25 | 26 | let size = Rectangle.Size(width: 100, height: 100) 27 | print("Rectangle.Size : ", size) 28 | 29 | let obj = Rectangle(origin: point, size: size) 30 | -------------------------------------------------------------------------------- /08.StructAndEnum/PropertyChange.swift: -------------------------------------------------------------------------------- 1 | struct ChangeCounter { 2 | var count: Int = 0 3 | var value: Int = 0 { 4 | didSet { 5 | count += 1 6 | } 7 | } 8 | init() {} 9 | } 10 | 11 | var counter = ChangeCounter() 12 | 13 | counter.value = 10 14 | counter.value = 20 15 | 16 | print(counter.count) // 2 17 | 18 | counter.value = 30 19 | 20 | print(counter.count) // 3 21 | -------------------------------------------------------------------------------- /08.StructAndEnum/StoredAndComputedProperty.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Computed Property, Stored Property 3 | */ 4 | struct Time { 5 | var minute : Int { 6 | get { 7 | return Int(sec / 60) 8 | } 9 | set { 10 | sec = newValue * 60 11 | } 12 | } 13 | var sec: Int = 0 14 | init() {} 15 | } 16 | 17 | 18 | var t = Time() 19 | t.minute = 10 20 | print(t.sec) 21 | 22 | let sec = t.minute 23 | print(sec) 24 | -------------------------------------------------------------------------------- /08.StructAndEnum/StructAndInitializer.swift: -------------------------------------------------------------------------------- 1 | struct MyStruct { 2 | var value1: Int 3 | 4 | var value2: Int = 0 5 | 6 | var value3: Int? 7 | 8 | var value4: Int! 9 | 10 | init() { 11 | value1 = 0 12 | } 13 | } 14 | 15 | let p = MyStruct() 16 | 17 | /* 18 | * 구조체 - Initializer 19 | */ 20 | 21 | struct Point { 22 | var x = 0 23 | var y = 0 24 | 25 | // Designated Initializer 26 | init(x: Int, y: Int) { 27 | self.x = x 28 | self.y = y 29 | } 30 | 31 | 32 | // Convenience Initializer 33 | init() { 34 | self.init(x: 0, y: 0) 35 | } 36 | } 37 | 38 | 39 | var p1 = Point(x: 10, y: 10) 40 | var p2 = Point() 41 | 42 | print(p1) 43 | print(p2) 44 | -------------------------------------------------------------------------------- /08.StructAndEnum/StructAndMethod.swift: -------------------------------------------------------------------------------- 1 | struct Director { 2 | var name: String 3 | func greeting() { 4 | print("\(name)이 인사를 합니다") 5 | } 6 | } 7 | 8 | let bong = Director(name: "봉준호") 9 | bong.greeting() -------------------------------------------------------------------------------- /08.StructAndEnum/StructAndMutating.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 구조체 - mutation 3 | */ 4 | 5 | struct Point { 6 | var x = 0 7 | var y = 0 8 | 9 | mutating func moveTo(x : Int, y : Int) { 10 | self.x = x 11 | self.y = y 12 | print("") 13 | } 14 | 15 | // 상태 변경 불가 - mutating 필요 16 | func change(x : Int) { 17 | // self.x = x // 에러 18 | } 19 | } 20 | 21 | 22 | var p = Point() 23 | p.change(x:10) 24 | 25 | p.moveTo(x:10, y: 20) 26 | -------------------------------------------------------------------------------- /08.StructAndEnum/StructAndStaticMethod.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 구조체 - 정적 메소드와 프로퍼티 3 | */ 4 | 5 | struct MyStruct { 6 | // 정적 메소드 정의 7 | static func staticFunc() { 8 | print("정적 메소드") 9 | } 10 | 11 | // 정적 프로퍼티 12 | static var staticProperty : Int! 13 | } 14 | 15 | // 정적 메소드 실행 16 | MyStruct.staticFunc() 17 | // 정적 프로퍼티 접근 18 | MyStruct.staticProperty = 10 -------------------------------------------------------------------------------- /09.Class/ClassAndInstance.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 클래스 정의와 객체 생성 3 | */ 4 | 5 | class MyClass { 6 | // 초기값을 설정한 프로퍼티 7 | var intProperty = 0 8 | 9 | // 초기값을 설정하지 않은 옵셔널 프로퍼티 10 | var floatProperty : Float? 11 | 12 | // 초기값을 설정하지 않은 논-옵셔널 프로퍼티. Initializer가 없으면 에러 발생 13 | // var strProperty : String 14 | } 15 | 16 | // 객체 생성 17 | var obj = MyClass() 18 | 19 | // 프로퍼티에 값 저장 20 | obj.intProperty = 10 21 | obj.floatProperty = 3.1 22 | 23 | // 프로퍼티에서 값을 얻어오기 24 | let val = obj.floatProperty 25 | print(val) // Optional. 3.1 -------------------------------------------------------------------------------- /09.Class/ClassAndMethod.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Method 3 | */ 4 | class Counter { 5 | var count = 0 6 | 7 | func increment() { 8 | count+=1 9 | } 10 | 11 | func increment(amount : Int) { 12 | count += amount 13 | } 14 | 15 | func increment(amount: Int, times : Int) { 16 | count += amount * times 17 | } 18 | 19 | func setCount(count : Int) { 20 | self.count = count // self를 이용해서 프로퍼티 접근 21 | } 22 | 23 | func reset() { 24 | count = 0 25 | } 26 | } 27 | 28 | // 객체 생성 29 | let counter = Counter() 30 | 31 | // 파리미터가 없는 메소드 호출 32 | counter.increment() 33 | print(counter.count) // 1 34 | 35 | // 파라미터가 1개인 메소드 호출 36 | counter.increment(amount: 5) 37 | print(counter.count) // 5 38 | 39 | // 파라미터가 2개인 메소드 호출 40 | counter.increment(amount:3, times: 5) 41 | print(counter.count) // 21 -------------------------------------------------------------------------------- /09.Class/ComputedProperty.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 저장 프로퍼티와 연산 프로퍼티 3 | */ 4 | class Person { 5 | // 상수 6 | let thisYear = 2019 7 | 8 | // 저장 프로퍼티 9 | var birthYear : Int = 0 10 | 11 | // 계산 프로퍼티 12 | var age : Int { 13 | get { 14 | // 파라미터 타입과 같은 타입의 값 반환 15 | return thisYear - birthYear 16 | } 17 | set { 18 | // newValue로 설정되는 값 전달 19 | print("newValue : ",newValue) 20 | birthYear = thisYear - newValue 21 | } 22 | } 23 | } 24 | 25 | 26 | var iu = Person() 27 | // 저장 프로퍼티 사용 28 | iu.birthYear = 1993 29 | 30 | // 계산 프로퍼티의 get 행위 31 | let age = iu.age 32 | age 33 | 34 | // 계산 프로퍼티의 set 행위 35 | iu.age = 23 36 | let birthYear = iu.birthYear 37 | -------------------------------------------------------------------------------- /09.Class/ConvenienceInitializer.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Designated, Convenience Initializer 3 | */ 4 | class MyClass { 5 | var a : Int 6 | var b : Int 7 | 8 | // Designated Intializer 9 | init() { 10 | a = 0 11 | b = 0 12 | } 13 | 14 | // Designated Intializer 15 | init(a:Int, b:Int) { 16 | self.a = a 17 | self.b = b 18 | } 19 | 20 | // Convenience Intializer 21 | convenience init(b:Int) { 22 | self.init() // Initializer delegation 23 | self.b = b 24 | } 25 | } 26 | 27 | 28 | // Designated Initializer로 객체 생성 29 | var obj1 = MyClass() 30 | var obj2 = MyClass(a: 1, b: 2) 31 | 32 | // Convenience Initializer로 객체 생성 33 | var obj3 = MyClass(b: 2) -------------------------------------------------------------------------------- /09.Class/Deinitializer.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 메모리 해제시 동작하는 deini 3 | */ 4 | class MyClass { 5 | deinit { 6 | // 객체 해제시 동작 7 | print("deinit") 8 | } 9 | } 10 | 11 | 12 | var obj : MyClass! = MyClass() 13 | obj = nil 14 | 15 | print("== END ==") 16 | -------------------------------------------------------------------------------- /09.Class/DesignatedInitializer.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Initializer 3 | */ 4 | class Rectangle { 5 | var width : Int 6 | var height : Int 7 | 8 | // 프로퍼티의 값을 기본 값으로 초기화 9 | init() { 10 | width = 0 11 | height = 0 12 | } 13 | 14 | // 파라미터가 있는 Initializer 15 | init(width : Int, height : Int) { 16 | self.width = width 17 | self.height = height 18 | } 19 | } 20 | 21 | 22 | var rect = Rectangle() 23 | 24 | var rect2 = Rectangle(width: 10, height: 20) -------------------------------------------------------------------------------- /09.Class/FailableInitializer.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Failable Initializer 3 | */ 4 | class Person { 5 | var birthYear : Int 6 | 7 | init?(birthYear : Int) { 8 | // 초기화 조건 검사 - 실패시 nil 반환 9 | if birthYear <= 1900 { 10 | return nil 11 | } 12 | else { 13 | // 초기값과 함께 선언한 프로퍼티는 초기화 14 | self.birthYear = birthYear 15 | } 16 | } 17 | deinit { 18 | // 객체 해제시 동작 19 | print("deinit") 20 | } 21 | } 22 | // nil 반환 - 옵셔널 타입 23 | let obj1 = Person(birthYear: 1890) 24 | print(obj1) 25 | 26 | // 강제 언래핑 27 | var obj2 = Person(birthYear: 1990)! 28 | print(obj2) 29 | 30 | // 옵셔널 바인딩 31 | if let obj3 = Person(birthYear: 2000) { 32 | print(obj3) 33 | } -------------------------------------------------------------------------------- /09.Class/InheritanceAndInitializer1.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 부모 클래스의 Initialiezer 상속하기. Case 1 3 | * 자식 클래스에 Designated Initialiezer가 없으면 상속 4 | */ 5 | 6 | // 부모 클래스 7 | class Parent { 8 | var a : Int 9 | 10 | // Designated Initializer 11 | init(a : Int) { 12 | self.a = a 13 | } 14 | 15 | // Convenience Initializer 16 | convenience init() { 17 | self.init(a : 0) 18 | } 19 | } 20 | 21 | class Child : Parent { 22 | // 초기값이 있기 때문에 Initializer 생략 가능 23 | var b = 100 24 | } 25 | 26 | 27 | // 부모 클래스에서 상속받은 Designated Initializer로 자식 클래스 객체 생성 28 | var childObj1 = Child(a: 10) 29 | 30 | // 부모 클래스에서 상속받은 Convenience Initializer로 자식 클래스 객체 생성 31 | var childObj2 = Child() 32 | -------------------------------------------------------------------------------- /09.Class/InheritanceAndInitializer2.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 자식 클래스에서 Initializer 재정의 3 | */ 4 | class Parent { 5 | var a : Int 6 | 7 | // Designated Initializer 8 | init(a : Int) { 9 | self.a = a 10 | } 11 | 12 | // Convenience Initializer 13 | convenience init() { 14 | self.init(a : 0) 15 | } 16 | } 17 | 18 | class Child : Parent { 19 | var b : Int 20 | 21 | // 초기화 메소드 재정의, Designated Initializer 22 | override init(a : Int) { 23 | self.b = 0 24 | super.init(a: a) 25 | } 26 | 27 | // Designated Initializer 28 | init(a : Int, b : Int) { 29 | self.b = b 30 | super.init(a: a) 31 | } 32 | } 33 | 34 | 35 | // 자식 클래스의 Designated Initializer로 객체 생성 36 | var obj1 = Child(a: 10, b : 20) 37 | 38 | // 재정의한 Designated Initializer로 객체 생성 39 | var obj2 = Child(a: 30) 40 | 41 | // 상속받은 Convenience Initializer로 객체 생성 42 | var obj3 = Child() 43 | -------------------------------------------------------------------------------- /09.Class/InheritanceAndInitializerNotInherited.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 자식 클래스에 Designated Initializer 작성하기 3 | // 4 | 5 | // 부모 클래스 6 | class Parent { 7 | var a : Int 8 | // 부모 클래스의 Designated Initializer 9 | init(a : Int) { 10 | self.a = 0 11 | } 12 | } 13 | 14 | // Designated Initializer를 작성한 자식 클래스 15 | class Child : Parent { 16 | var b : Int 17 | 18 | // Designated Initializer 19 | init(a : Int, b : Int) { 20 | // 같은 클래스의 초기화 먼저 21 | self.b = b 22 | // 부모 클래스의 Designated Initializer 호출 23 | super.init(a: a) 24 | } 25 | } 26 | 27 | 28 | var obj = Child(a: 10, b: 20) 29 | 30 | // 에러. 자식 클래스에 Designated Initializer를 작성했기 때문에 Initializer 상속이 안된다. 31 | //var obj2 = Child(a : 10) // 에러 -------------------------------------------------------------------------------- /09.Class/InheritanceAndOverride.swift: -------------------------------------------------------------------------------- 1 | class Rectangle { 2 | // 저장 프로퍼티 3 | var width = 0, height = 0 4 | 5 | // 계산 프로퍼티 6 | var isSquare : Bool { 7 | return width == height 8 | } 9 | 10 | // 메소드 11 | func size() -> Int { 12 | return width * height 13 | } 14 | } 15 | 16 | // 클래스 상속 17 | class Square : Rectangle { 18 | // 부모 클래스의 size 메소드 재정의 19 | override func size() -> Int { 20 | return width * width 21 | } 22 | // 저장 프로퍼티의 감시자 재정의 23 | override var width : Int { 24 | didSet { 25 | if height != width { 26 | height = width 27 | } 28 | } 29 | } 30 | 31 | // 계산 프로퍼티의 get/set 기능 재정의 32 | override var isSquare : Bool { 33 | return true 34 | } 35 | } 36 | 37 | var square = Square() 38 | square.width = 90 39 | square.height = 100 40 | square.isSquare 41 | square.size() 42 | -------------------------------------------------------------------------------- /09.Class/InheritanceAndRequiredInitializer.swift: -------------------------------------------------------------------------------- 1 | class Parent { 2 | var a : Int 3 | var b : Int 4 | 5 | // Required Designated Initializer 6 | required init(a : Int, b : Int) { 7 | self.a = a 8 | self.b = b 9 | } 10 | 11 | // Designated Initializer 12 | init(a : Int) { 13 | self.a = a 14 | self.b = 0 15 | } 16 | 17 | // Required Convenience Initializer 18 | required convenience init() { 19 | self.init(a : 0) 20 | } 21 | } 22 | 23 | 24 | 25 | class Child : Parent { 26 | var c : Int 27 | 28 | // required Designated Initializer 재정의 29 | required init(a : Int, b : Int) { 30 | self.c = 0 31 | super.init(a: a, b : b) 32 | } 33 | 34 | // required Convenience Initializer 재정의 35 | required convenience init() { 36 | self.init(a : 0, b : 0) 37 | } 38 | } 39 | 40 | 41 | // 자식 클래스에서 required 조건으로 재정의한 Designated Initializer로 객체 생성 42 | var obj1 = Child(a: 10, b : 20) 43 | 44 | // 자식 클래스의 Convenience Initializer로 생성 45 | var obj2 = Child() 46 | 47 | 48 | class AnotherChild : Parent { 49 | // Designated Initializer가 없으므로 초기화 메소드 상속 50 | } 51 | 52 | // 부모 클래스에서 상속받은 Initializer로 객체 생성 53 | var obj3 = AnotherChild(a: 10) 54 | var obj4 = AnotherChild(a: 20, b: 30) -------------------------------------------------------------------------------- /09.Class/InitializerAndFailableInitializer.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Failable Initializer의 재정의 3 | */ 4 | class Parent { 5 | var value : Int 6 | 7 | // Failable Initializer 8 | init?(value : Int) { 9 | if value <= 0 { 10 | self.value = 0 11 | return nil 12 | } 13 | self.value = value 14 | } 15 | 16 | // Designated Initializer 17 | init() { 18 | self.value = 0 19 | } 20 | } 21 | 22 | // 23 | // Failable Initializer를 Failable Inintializer로 재정의 24 | // 25 | 26 | class Child : Parent { 27 | override init?(value: Int) { 28 | // super.init 호출 필요 29 | super.init(value: 0) 30 | // 유효성 검사 31 | if value < 0 { 32 | return nil 33 | } 34 | self.value = value 35 | } 36 | } 37 | 38 | let obj = Child(value: 0) // Optional 39 | print(obj) 40 | 41 | // 42 | // Failable initializer를 non-failable initializer로 재정의 43 | // 44 | 45 | class Child2 : Parent { 46 | override init(value : Int) { 47 | super.init() 48 | } 49 | } 50 | 51 | let obj2 = Child2(value: 0) 52 | print(obj2) 53 | 54 | 55 | // 56 | // Non-Failable Initializer를 Failable initializer로 재정의 - 에러 57 | // 58 | 59 | class Child3 : Parent { 60 | // override init?() { 61 | // super.init(value: 10) 62 | // } 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /09.Class/PropertyLazy.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Lazy Initialized Property 3 | */ 4 | class Person { 5 | lazy var phone = Phone() 6 | } 7 | 8 | class Phone { 9 | var number : String 10 | init() { 11 | print("Phone 객체 생성") 12 | number = "010-1234-5678" 13 | } 14 | } 15 | 16 | // 객체가 생성되지만 Phone 객체는 생성 안됨 17 | print("Person 객체 생성") 18 | let obj = Person() 19 | 20 | // lazy 프로퍼티에 접근. Phone 객체 생성(초기에만) 21 | print("phone에 접근") 22 | print(obj.phone.number) -------------------------------------------------------------------------------- /09.Class/ReferenceType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Reference Type vs Value Type 3 | // 4 | 5 | class MyClass { 6 | var value : Int = 0 7 | } 8 | 9 | var obj1 = MyClass() // 객체 생성 10 | var obj2 = obj1 11 | 12 | // 프로퍼티의 값을 변경 13 | obj1.value = 10 14 | 15 | print(obj1.value) 16 | print(obj2.value) -------------------------------------------------------------------------------- /09.Class/property_observing.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Property value-change Observing 3 | */ 4 | class Rectangle { 5 | var width = 0 6 | var height : Int = 0 { 7 | // 프로퍼티에 값이 설정되기 전에 동작. 새로운 값은 newValue로 접근 8 | willSet { 9 | print("사각형 높이 변경 예정 : \(newValue)") 10 | } 11 | // 프로퍼티에 값이 설정된 후에 동작. 변경 전의 값은 oldValue로 접근 12 | didSet { 13 | // 0보다 작으면 0으로 변경 14 | if height < 0 { 15 | height = 0 16 | } 17 | print("사각형 높이 변경됨. 기존 높이 : \(oldValue) -> 새로운 높이 : \(height)") 18 | } 19 | } 20 | 21 | init() { 22 | // Initializer에서 프로퍼티 값 변경에는 동작하지 않는다. 23 | width = 1 24 | height = 1 25 | } 26 | } 27 | 28 | 29 | print("== 객체 생성") 30 | var obj = Rectangle() 31 | 32 | print("== 프로퍼티 변경 시작") 33 | obj.height = 50 34 | obj.height = -30 35 | print(obj.height) // 0 36 | -------------------------------------------------------------------------------- /09.Class/type_method.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 타입 메소드와 인스턴스 메소드 3 | */ 4 | class MyClass { 5 | var property = 0 6 | 7 | // 타입 메소드 8 | static func typeMethod() { 9 | // property = 2 // 에러. 타입 메소드에서 프로퍼티 접근 불가 10 | print("Type method works") 11 | } 12 | 13 | func intanceMethod() { 14 | property = 1 // 인스턴스 메소드에서 프로퍼티 접근 가능 15 | print("Instance method works") 16 | } 17 | } 18 | 19 | 20 | var obj = MyClass() 21 | obj.intanceMethod() 22 | 23 | MyClass.typeMethod() -------------------------------------------------------------------------------- /09.Class/type_property.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 타입 프로퍼티 3 | */ 4 | class Rectangle { 5 | // 인스턴스 프로퍼티 6 | var width : Int = 0 7 | 8 | // 계산 타입 프로퍼티 9 | static var name : String { 10 | return "사각형" 11 | } 12 | // 저장 타입 프로퍼티 13 | static var edge = 4 14 | } 15 | 16 | 17 | // 인스턴스 프로퍼티 접근 18 | var obj = Rectangle() 19 | obj.width = 10 20 | 21 | // 타입 프로퍼티 접근 22 | print(Rectangle.edge) // 4 23 | print(Rectangle.name) -------------------------------------------------------------------------------- /09.Inheritance/example1.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 다각형을 다루기 위한 부모 클래스 Shape에 Failable Intializer와 non-Failable Initializer 3 | * 자식 클래스인 Rectangle에 초기화 메소드를 작성한 예제 4 | */ 5 | 6 | class Shape { 7 | var edge : Int 8 | 9 | // Failable Initializer 10 | init?(numberOfEdge : Int) { 11 | if numberOfEdge < 1 { 12 | edge = 0 13 | return nil 14 | } 15 | else { 16 | edge = numberOfEdge 17 | } 18 | } 19 | 20 | // Designated Initializer 21 | init() { 22 | edge = 0 23 | } 24 | } 25 | 26 | 27 | class Rectangle : Shape { 28 | var width = 0 29 | var height = 0 30 | 31 | override init() { 32 | super.init() 33 | } 34 | 35 | // Failable Initializer 36 | init?(width : Int, height : Int) { 37 | // 부모 클래스의 Failable Initializer로 위임 -> Failable Initializer 38 | super.init(numberOfEdge: 4) 39 | 40 | // 초기값과 함께 선언한 프로퍼티는 초기화 조건 체크 이후에 초기화 가능 41 | if width < 0 || height < 0 { 42 | return nil 43 | } 44 | else { 45 | self.width = width 46 | self.height = height 47 | } 48 | } 49 | } 50 | 51 | 52 | let rect1 : Rectangle = Rectangle() 53 | 54 | // Failable Initializer로 객체 생성 55 | let rect2 : Rectangle? = Rectangle(width: 10, height: 10) 56 | let rect3 : Rectangle? = Rectangle(width: 10, height: -10) // nil 57 | -------------------------------------------------------------------------------- /09.Inheritance/example2.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Shape 클래스를 상속하는 삼각형 클래스 Triangle 3 | */ 4 | 5 | import Foundation 6 | 7 | class Shape { 8 | var edge : Int 9 | 10 | init(numberOfEdge : Int) { 11 | edge = numberOfEdge 12 | } 13 | 14 | func description() -> String { 15 | return "\(edge) 각형" 16 | } 17 | 18 | func size() -> Double { 19 | return 0 20 | } 21 | } 22 | 23 | // 자식 클래스 - 사각형 24 | class Rectangle : Shape { 25 | var width : Double 26 | var height : Double 27 | 28 | // Designated Initializer 29 | init(width : Double, height : Double) { 30 | self.width = width 31 | self.height = height 32 | 33 | // 초기화 메소드 위임 - 부모 클래스의 Designated Initializer 34 | super.init(numberOfEdge: 4) 35 | } 36 | 37 | // Convenience Initializer 38 | convenience init() { 39 | // 초기화 메소드 위임 - 같은 클래스 40 | self.init(width : 0, height : 0) 41 | } 42 | 43 | // 재정의 44 | override func description() -> String { 45 | return "사각형 가로 \(width) 세로 \(height)" 46 | } 47 | 48 | // size 메소드 메소드 49 | override func size() -> Double { 50 | return Double(width * height) 51 | } 52 | } 53 | 54 | // 자식 클래스 - 삼각형 55 | class Triangle : Shape { 56 | var a = 0.0 57 | var b = 0.0 58 | var c = 0.0 59 | 60 | // Designated Initializer 61 | init(a : Double, b : Double, c : Double) { 62 | self.a = a 63 | self.b = b 64 | self.c = c 65 | // 초기화 메소드 위임 66 | super.init(numberOfEdge: 3) 67 | } 68 | 69 | // 재정의 70 | override func description() -> String { 71 | return "삼각형 \(a), \(b), \(c)" 72 | } 73 | 74 | override func size() -> Double { 75 | // 세 변의 길이로 삼각형 넓이 구하기 - 헤론 공식 76 | let s : Double = ( a + b + c ) / 2 77 | let result = sqrt( s * (s - a) * (s - b) * (s - c) ) 78 | return result 79 | } 80 | } 81 | 82 | 83 | var obj1 = Rectangle(width: 10, height: 20) 84 | print("\(obj1.description()) , size : \(obj1.size())") 85 | 86 | var obj2 = Triangle(a: 3, b: 4, c: 5) 87 | print("\(obj2.description()), size : \(obj2.size())") 88 | 89 | 90 | -------------------------------------------------------------------------------- /09.Inheritance/initializer_override_failable.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Failable Initializer 상속 3 | */ 4 | class Parent { 5 | var value : Int 6 | 7 | // Failable Initializer 8 | init?(value : Int) { 9 | if value <= 0 { 10 | self.value = 0 11 | return nil 12 | } 13 | self.value = value 14 | } 15 | } 16 | 17 | 18 | class Child : Parent { 19 | // Failable Initializer 재정의 20 | override init?(value: Int) { 21 | // super.init 호출 필요 22 | super.init(value: 0) 23 | // 유효성 검사 24 | 25 | if value < 0 { 26 | return nil 27 | } 28 | self.value = value 29 | } 30 | } 31 | 32 | var obj = Child(value: 0) 33 | obj 34 | -------------------------------------------------------------------------------- /09.Inheritance/super_self.swift: -------------------------------------------------------------------------------- 1 | class Parent { 2 | func description() -> String { 3 | return "Parent 클래스" 4 | } 5 | } 6 | 7 | class Child : Parent { 8 | // 재정의 9 | override func description() -> String { 10 | return "Child 클래스" 11 | } 12 | func printDescription() { 13 | // 부모 클래스에 구현한 description 메소드 14 | print("super.description : \(super.description())") 15 | print("self.description : \(self.description())") 16 | } 17 | } 18 | 19 | var obj = Child() 20 | obj.printDescription() -------------------------------------------------------------------------------- /09.Inheritance/two_phase_initialization.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Two Phase Initialization 3 | */ 4 | 5 | class Parent { 6 | var a : Int 7 | 8 | // 부모 클래스의 초기화 메소드 9 | init() { 10 | // 1단계(Phase 1) : 프로퍼티 초기화 11 | a = 0 12 | // 2단계(Phase 2) 초기화 13 | } 14 | } 15 | 16 | class Child : Parent { 17 | var b : Int 18 | 19 | init(a : Int, b : Int) { 20 | // 1단계(Phase 1) : 자식 클래스의 초기화에서 부모 클래스까지 초기화 21 | self.b = b 22 | super.init() 23 | 24 | // 2단계(Phase 2) : 부모 클래스의 값 재설정. 25 | self.a = a 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /10.Closure/array_sort.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * array의 sorted에 클로저 사용하기 3 | */ 4 | 5 | var array = [2, 3, 1, 5, 4]; 6 | 7 | // 함수 타입이 (Int, Int) -> Bool 인 함수 8 | func sortFunc(a : Int, b : Int) -> Bool { 9 | return a < b 10 | } 11 | 12 | let sorted = array.sorted(by: sortFunc) 13 | print(sorted) 14 | 15 | let sorted2 = array.sorted(by: { (a:Int, b:Int) -> Bool in 16 | return a < b 17 | }) 18 | print(sorted2) 19 | 20 | 21 | // 타입 선언 생략 22 | let sorted3 = array.sorted(by: { a, b -> Bool in return a < b } ) 23 | print(sorted3) 24 | 25 | // 1줄인 경우 return 생략 26 | let sorted4 = array.sorted(by: { a, b -> Bool in a < b } ) 27 | print(sorted4) 28 | 29 | // 반환 타입 선언 생략 30 | let sorted5 = array.sorted(by: { a, b in a < b }) 31 | print(sorted5) 32 | 33 | // 파라미터 선언 생략 34 | let sorted6 = array.sorted(by: { $0 < $1 }) 35 | print(sorted6) 36 | 37 | // Trailing 38 | let sorted7 = array.sorted{ $0 < $1 } 39 | print(sorted7) 40 | 41 | // Operator Function 42 | let sorted8 = array.sorted(by: < ) 43 | print(sorted8) -------------------------------------------------------------------------------- /10.Closure/autoclosure.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * autoclosure 3 | */ 4 | var value = 0 5 | 6 | func doIt(_ arg : () -> () ) { 7 | arg() 8 | } 9 | 10 | doIt( { value += 10 } ) 11 | print("클로저 입력, 실행 결과", value) 12 | 13 | func doIt2(_ arg : @autoclosure () -> () ) { 14 | arg() 15 | } 16 | 17 | doIt2(value += 10) 18 | print("autoclosure 실행 결과 : ",value) 19 | 20 | 21 | /* 22 | * autoclosure + escaping 23 | */ 24 | 25 | 26 | var escapedVar : ( () -> () )! 27 | 28 | func doIt3(_ arg : @escaping @autoclosure () -> () ) { 29 | arg() 30 | escapedVar = arg 31 | } 32 | 33 | doIt3( value += 10 ) 34 | print("autoclosure, escping 결과 : ", value) 35 | 36 | escapedVar() 37 | print("escaping된 프로퍼티 실행 : ", value) -------------------------------------------------------------------------------- /10.Closure/capture.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 값 읽기 3 | // 4 | print("= Read Value") 5 | func greeting() -> () -> () { 6 | let str = "Hello" 7 | return { 8 | // () -> () in 9 | print(str) 10 | } 11 | } 12 | 13 | let str = "Good Morning" 14 | let ret = greeting() 15 | ret() // "Hello" 출력 16 | 17 | 18 | func increment() -> (Int) -> Int { 19 | var count = 0 20 | return { 21 | count += $0 22 | return count 23 | } 24 | } 25 | 26 | 27 | // 28 | // 값을 쓰기 29 | // 30 | print("= Write Value") 31 | func increment(by amount : Int) -> () -> () { 32 | // 클로저에서 count 캡춰 33 | var count = 0 34 | return { 35 | count += amount 36 | print(count) 37 | } 38 | } 39 | 40 | var step2 = increment(by: 2) 41 | step2() // 2 42 | step2() // 4 43 | 44 | var step3 = increment(by: 3) 45 | step3() // 3 46 | step3() // 6 47 | step3() // 9 48 | 49 | 50 | 51 | // 52 | // 레퍼런스 타입의 객체 캡처 53 | // 54 | print("= Capture Reference") 55 | class MyClass { 56 | var value = 0 57 | func printValue() { 58 | print(value) 59 | } 60 | } 61 | 62 | 63 | func increment2(by amount : Int) -> () -> () { 64 | let countObj = MyClass() 65 | return { 66 | countObj.value += amount 67 | countObj.printValue() 68 | } 69 | } 70 | 71 | 72 | var step4 = increment2(by: 2) 73 | step4() 74 | step4() 75 | 76 | var step5 = increment2(by: 3) 77 | step5() 78 | step5() 79 | step5() 80 | -------------------------------------------------------------------------------- /10.Closure/capture_reference.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 클로저에서 접근한 객체를 소유한다. 3 | */ 4 | 5 | class Counter { 6 | var value : Int = 0 7 | 8 | func incresed() -> () -> Int { 9 | return { 10 | self.value += 1 11 | return self.value 12 | } 13 | } 14 | 15 | deinit { 16 | print("Deinit") 17 | } 18 | } 19 | 20 | print("== 첫번째 예제 시작") 21 | 22 | // 객체 생성 23 | print("객체 생성") 24 | var obj : Counter! = Counter() 25 | 26 | print("클로저 접근 및 사용") 27 | let closure : () -> Int = obj.incresed() 28 | print(closure()) 29 | print(closure()) 30 | 31 | // 객체 소유권 해제 32 | print("객체 소유권 해제") 33 | obj = nil 34 | 35 | print("== 첫번째 예제 끝") 36 | 37 | print("== 두번째 예제 시작") 38 | 39 | print("객체 생성") 40 | var obj2 : Counter! = Counter() 41 | 42 | print("클로저 접근 및 사용") 43 | var closure2 : ( ()->Int )! = obj2.incresed() 44 | 45 | print(closure2()) 46 | 47 | print("객체 소유권 해제") 48 | obj2 = nil 49 | print("클로저 nil 대입") 50 | closure2 = nil 51 | 52 | print("== 두번째 예제 끝") 53 | 54 | 55 | 56 | // 57 | // 객체를 소유하지 않는 클로저 58 | // 59 | 60 | class Counter2 { 61 | var value : Int = 0 62 | 63 | // unowned를 이용한 객체 소유 방지 64 | func increment() -> () -> Int { 65 | return { 66 | [unowned self] in 67 | self.value += 1 68 | return self.value 69 | } 70 | } 71 | 72 | // weak를 이용한 객체 소유 방지 73 | func increment2() -> () -> Int { 74 | return { 75 | [weak self] in 76 | self?.value += 1 77 | return (self?.value)! 78 | } 79 | } 80 | 81 | deinit { 82 | print("Deinit") 83 | } 84 | } 85 | 86 | print("== 세번째 예제 시작") 87 | print("객체 생성") 88 | var obj3 : Counter2! = Counter2() 89 | 90 | print("클로저 접근") 91 | var closure3 : (()->Int)! = obj3.increment() 92 | print(closure3()) 93 | print(closure3()) 94 | 95 | print("객체 소유권 해제") 96 | obj3 = nil 97 | 98 | // 객체가 해제됐으므로 호출시 에러 99 | // closure3() // Error 100 | print("== 세번째 예제 끝") 101 | 102 | -------------------------------------------------------------------------------- /10.Closure/closure_api.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 클로저를 사용하는 API 작성하기 3 | */ 4 | 5 | // 6 | // 클로저를 반환하는 함수 7 | // 8 | 9 | // ()->() 를 반환값의 타입으로 정의한 함수 10 | func greeting() -> () -> Void { 11 | // 함수 타입 : () -> () 12 | func sayGoodmorning() { 13 | print("Good Morning") 14 | } 15 | 16 | return sayGoodmorning 17 | } 18 | 19 | // 함수 호출 결과는 타입이 ()->()인 함수 20 | let ret = greeting() 21 | ret() 22 | 23 | greeting()() // 붙여서도 사용 24 | 25 | 26 | // Inline 방식 27 | func greeting2() -> () -> () { 28 | return { 29 | () -> () in 30 | print("How are you?") 31 | } 32 | } 33 | 34 | let ret2 = greeting2() 35 | ret2() 36 | 37 | // Inline 방식2 38 | func greeting3() -> () -> () { 39 | return { 40 | print("Fine Thank you and you?") 41 | } 42 | } 43 | 44 | let ret3 = greeting3() 45 | ret3() 46 | 47 | 48 | // 49 | // 파라미터로 사용 50 | // 51 | 52 | func add(_ i : Int, _ j : Int, _ handler: (Int) -> Void ) { 53 | let sum = i + j 54 | // 파라미터로 전달된 클로저 실행. 55 | handler(sum) 56 | } 57 | 58 | add(3, 4, { (result : Int) -> Void in 59 | print("3 + 4 = \(result)") 60 | }) 61 | 62 | 63 | // Trailing closure 64 | add(5, 6) { (result) -> Void in 65 | print("5 + 6 = \(result)") 66 | } 67 | 68 | // 69 | // Optional 70 | // 71 | 72 | func multiply(_ i : Int, _ j : Int, _ handler : ((Int) -> Void)? ) { 73 | let sum = i * j 74 | if let closure = handler { 75 | closure(sum) 76 | } 77 | } 78 | 79 | multiply(7, 8, nil) 80 | multiply(9, 10) { print($0) } // trailing closure 81 | -------------------------------------------------------------------------------- /10.Closure/closure_inClass.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 클로저를 사용하는 클래스 3 | */ 4 | 5 | class MyClosureClass { 6 | var value = 0 7 | 8 | // 클로저 타입의 프로퍼티 9 | var closureProperty : (()->Int)! 10 | 11 | // 클로저를 반환하는 메소드 12 | func showAndPrint() -> () -> () { 13 | return { 14 | // self를 이용해서 접근한다. 15 | print(self.value) 16 | } 17 | } 18 | 19 | } 20 | 21 | var obj = MyClosureClass() 22 | obj.closureProperty = { 23 | return 0 24 | } 25 | obj.closureProperty() -------------------------------------------------------------------------------- /10.Closure/escaping.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 클로저 escaping, noescape 3 | */ 4 | 5 | 6 | // 7 | // non-escaping 속성의 클로저는 범위 밖으로 전달 불가 8 | // 9 | class MyClass1 { 10 | var prop : (() -> ())! 11 | func closureFunc(_ arg : () -> () ) { 12 | // self.prop = arg // Error 13 | } 14 | } 15 | 16 | // 17 | // escaping 속성의 클로저는 함수(메소드) 외부로 전달 가능 18 | // 19 | class MyClass2 { 20 | var prop : (() -> ())! 21 | func closureFunc(_ arg : @escaping () -> () ) { 22 | self.prop = arg 23 | } 24 | } 25 | 26 | 27 | // 28 | // non-escaping 속성의 클로저는 non-escaping 속성의 파라미터로 전달 가능 29 | // 30 | class MyClass3 { 31 | func closureFunc(_ arg : () -> () ) { 32 | otherFunc(arg) 33 | } 34 | 35 | func otherFunc(_ arg : () -> () ) { 36 | print("Other function works") 37 | arg() 38 | } 39 | } 40 | 41 | let obj3 = MyClass3() 42 | obj3.closureFunc { 43 | print("escaping example") 44 | } 45 | 46 | // 47 | // non-escaping 속성의 클로저는 escaping 속성의 파라미터로 전달 불가 48 | // 49 | class MyClass4 { 50 | func closureFunc(_ arg : () -> () ) { 51 | // otherFunc(arg) 52 | } 53 | 54 | func otherFunc(_ arg : @escaping () -> () ) { 55 | print("Other function works") 56 | arg() 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /10.Closure/function_object.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 클로저와 함수 객체 3 | */ 4 | 5 | // 함수 정의 6 | func sayHello() { 7 | print("Hello") 8 | } 9 | 10 | // 함수 호출 11 | sayHello() 12 | 13 | // hello의 타입은? 14 | let hello = sayHello 15 | hello() 16 | 17 | 18 | // hello 함수의 함수 타입 19 | let fn1: () -> () = sayHello 20 | fn1() 21 | 22 | let fn2: () -> Void = sayHello 23 | fn2() -------------------------------------------------------------------------------- /10.Closure/function_type.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 함수 타입 3 | */ 4 | 5 | // 함수 타입 : () -> (), () -> Void, (Void) -> (), (Void) -> Void 6 | func sayHello() { 7 | print("Hello") 8 | } 9 | 10 | // 파라미터의 타입 : () -> (). 11 | func greet1(_ greeting : () -> Void) { 12 | // 파라미터로 전달받은 함수 실행 13 | print("파라미터 타입이 () -> Void인 함수 실행") 14 | greeting() 15 | } 16 | 17 | // 함수의 참조를 이용 18 | let hello = sayHello 19 | greet1(hello) 20 | 21 | // 직접 함수 이름 입력 22 | greet1(sayHello) 23 | 24 | 25 | // 파라미터가 1개. 함수 타입 : String -> Void, String -> () 26 | func sayBye(who : String) { 27 | print("byebye \(who)") 28 | } 29 | 30 | func greet2(_ greeting : (String) -> Void) { 31 | print("파라미터 타입이 String -> Void 함수 실행") 32 | greeting("IU") 33 | } 34 | 35 | greet2(sayBye) 36 | 37 | // 파라미터가 2개, 반환 타입이 있는 함수. 함수 타입 : (String, String) -> (), (String, String) -> Void 38 | func say(who : String, what : String) { 39 | print("say \(what) to \(who)") 40 | } 41 | 42 | func greet3(_ greeting : (String, String) -> ()) { 43 | print("파라미터 타입이 (String, String) -> Void 함수 실행") 44 | greeting("IU","좋은날") 45 | } 46 | 47 | greet3(say) 48 | 49 | // 다음 두 함수의 함수 타입은 같다. 50 | 51 | // 함수 타입 : (Int, Int) -> Int 52 | func add(i : Int, j : Int) -> Int { 53 | return i + j 54 | } 55 | 56 | // 함수 타입 : (Int, Int) -> Int 57 | func multiply(i : Int, j : Int) -> Int { 58 | return i * j 59 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swift5 Samples 2 | Swift5 Samples 3 | 4 | ## 01.Data 5 | 값과 변수, 상수, 문장 작성 방법 6 | 7 | ### 리터럴 8 | * Literal_Number : 숫자형 값 9 | * Literal_String : 문자형 값 10 | * Literal_Range : 범위값 11 | * Nil : nil 12 | 13 | ### 변수와 상수 14 | * VarAndConstant : 변수와 상수 15 | * Print : 콘솔에 값 출력하기 16 | * Statement : Swift 코드 문장 작성하기 17 | 18 | ### 연산자 19 | * Operator : 연산자 20 | 21 | ## 02.기본 타입(Type) 22 | Swift의 기본 타입 23 | 24 | * Bool : 부울 타입 25 | * Int : 정수형 타입 26 | * Float : 실수형 타입 27 | * Character : Character 타입 28 | * String : 문자열 타입 29 | * String_Modify : 문자열 수정 30 | * String_Substring : 부분 문자열 31 | * String_Compare : 문자열 비교 32 | * String_Views : 문자열과 뷰 33 | * String_Founcation : 파운데이션 프레임워크 - 포맷 문자열 생성, 문자열 비교, 트리밍, 찾기 34 | * String_IO : 문자열 저장/읽기. Foundation 필요 35 | * Range : Range, ClosedRange, CountableRange, PartialRangeThrough 타입 36 | * TypeOf : 타입 정보 얻기 37 | * Unicode : 유니코드 다루기(작성중) 38 | 39 | ## 03. 다수의 데이터 다루기(CollectionType) 40 | 다수의 데이터를 다루는 타입 41 | 42 | * Tuple : 튜플 43 | * Array : 배열 44 | * Dictionary : 딕셔너리 45 | * Set : 셋 46 | * ComplexCollection : 복합 콜렉션 타입 47 | * ValueType : 밸류 타입 48 | 49 | ## 04.제어문(Controls) 50 | Swift의 반복, 조건문 51 | 52 | ### 반복 53 | * for : for 반복문 54 | * while : while, repeat-while 반복문 55 | * label : label을 이용한 흐름 제어문 56 | 57 | ### 조건 58 | * if : if 조건문 59 | * guard : guard 60 | * switch_case : switch-case 61 | * version-check : #avilable을 이용한 플랫폼, 버전 체크 62 | 63 | ## 05.옵셔널(Optional) 64 | 65 | * Optional : 옵셔널 타입 66 | * NilCheck : nil 여부 확인하기 67 | * ForcedUnwrapping: 강제 언래핑 68 | * OptionalBinding : 옵셔널 바인딩, if/guard 사용 69 | * NilCoalescing : nil 병합 연산자 ?? 70 | * OptionalChain : 옵셔널 체인 71 | * IUO : 암시적 언래핑 옵셔널(Implicitly Unwrapped Optional) 72 | 73 | ## 06.커스텀 타입(CustomType) 74 | 커스텀 타입 정의하기 75 | 76 | * Struct : 구조체로 커스텀 타입 정의하기 77 | * Class : 클래스로 커스텀 타입 정의하기 78 | * Enum : Enum으로 커스텀 타입 정의하기 79 | * Complex : 복합 타입 정의 80 | * Typealias : 타입 별칭 정하기 81 | * ValueAndReferenceType : 밸류 타입, 레퍼런스 타입 82 | 83 | ## 07.함수(Function) 84 | 함수 정의와 실행하기 85 | 86 | * Function : 함수 정의, 실행하기, 반환값 87 | * Parameter : 함수 파라미터, 외부 파라미터 설정 88 | * overloading : 같은 함수 이름 but 다른 함수 파라미터 타입, 다른 외부 파라미터 이름. 89 | * ParameterDefaultValue : 기본값을 가진 파라미터 90 | * ParameterVaridic : 가변 길이 파라미터 91 | * ParameterInout : Inout 파라미터 92 | * OptionalParamReturn : 파라미터나 반환값으로 nil 다루기 93 | * NestedFunction : 함수 내부에 함수 정의하기 94 | 95 | ## 08.구조체와 Enum 96 | 97 | ### 프로퍼티 98 | * StoredAndComputedProperty : 저장 프로퍼티, 연산 프로퍼티 99 | * PropertyChange : 프로퍼티 변경 감지 100 | 101 | ### 구조체 102 | 103 | * StructAndMethod : 구조체와 메소드 104 | * StructAndMutating : Mutatable 메소드 작성 105 | * StructAndStaticMethod : 정적 메소드와 정적 프로퍼티 106 | * StructAndInitializer : 구조체 초기화 107 | 108 | ### Enum 타입 109 | 110 | * EnumAndMethod : Enum 타입과 메소드 111 | * EnumAndAssociation : Enum과 Association Value 112 | 113 | * NestedType : 중첩 타입 114 | * ImmutableAndMutable : Mutable API, Immutable API 115 | 116 | 117 | ## 05.클래스(Class) 118 | 119 | ### 클래스 정의, 객체 생성, 프로퍼티, 메소드 120 | * ClassAndInstance : 클래스 정의와 객체 생성, 프로퍼티 121 | * ComputedProperty : 연산 프로퍼티 122 | * ClassAndMethod : 클래스 내 메소드 정의와 호출 123 | * ReferenceType : 클래스는 레퍼런스 타입 124 | * PropertyLazy : 늦은 초기화(Lazy initialize) 프로퍼티 125 | 126 | ### Initializer, Deinit 127 | * DesignatedInitializer : 클래스와 Designated Initializer 128 | * ConvenienceInitializer : Convenince Initializer 129 | * FailableInitializer : Failable Initializer 130 | * Deinitializer : Deinitializer 131 | 132 | ### 상속 133 | * InheritanceAndOverride : 클래스 상속과 메소드 재정의 134 | * InheritanceAndInitializer1 : 클래스 상속과 부모 클래스의 Initializer 상속 - 자식 클래스에 Designated Initializer 작성 안함 135 | * InheritanceAndInitializer2 : 클래스 상속과 부모 클래스의 Initializer 상속 - 자식 클래스가 부모 클래스의 모든 Designated 재정의 136 | * InheritanceAndInitializerNotInherited : 자식 클래스에 Designated Initializer 작성 - Initializer 상속 안함 137 | * InitializerAndFailableInitializer : Failable Initializer 재정의 138 | * InheritanceAndRequiredInitializer : Required Initializer 작성하기 139 | 140 | ### 타입 메소드, 프로퍼티, 프로퍼티 감시 141 | * type_method : 타입 메소드 142 | * type_property : 타입 프로퍼티 143 | * property_observing : 프로퍼티 감시 144 | * property_lazy : 늦은 프로퍼티 초기화 145 | 146 | ### 분류중 147 | - 상속, 재정의 148 | * override : 상속과 재정의 149 | * super_self : 클래스 상속과 self, super 참조 150 | * initializer_inherite1 : Initializer 상속. 자식 클래스에 Designated Initializer를 작성하지 않은 경우 151 | * initializer_in_child : 자식 클래스에 Designated Initializer 작성하기 152 | * initializer_in_child_convenience : 자식 클래스에 Convenience Initializer 작성하기 153 | * initializer_override : Initializer 재정의 154 | * initializer_inherite2 : Initializer 상속. 자식 클래스에서 모든 Designated Initializer를 재정의하는 경우 Convenience Initializer 상속 155 | * two_phase_initialization : 2단계 초기화 156 | * initializer_override_failable : Failable initializer 재정의 157 | 158 | ## 10.클로저(Closure) 159 | * function_object : 함수를 객체로 다루기 160 | * function_type : 함수 타입 161 | * array_sort : 배열의 API에서 클로저 사용 162 | * closure_api : 클로저 사용 함수 작성하기 163 | * closure_inClass : 클래스 내 메소드와 프로퍼티로 사용하기 164 | * capture : 클로저와 캡춰 165 | * capture_reference : 클로저와 객체 캡춰, 캡춰시 객체 소유하지 않기(unowned) 166 | * escaping : non-escaping, escaping 클로저 167 | * autoclosure : autoclosure 168 | 169 | ## 11.프로토콜(Protocol) 170 | * protocol_basic : 프로토콜 선언, 클래스와 구조체 채택 171 | * static_method : 프로토콜 내 타입 메소드 172 | * property : 프로토콜 내 프로퍼티 선언 173 | * initializer : 프로토콜 내 Initializer 선언 174 | * protocol_type : 프로토콜을 타입으로 사용 175 | * class_only : 클래스 전용 프로토콜 176 | * protocol_extension : 프로토콜 확장 177 | 178 | ## 12.ARC 179 | - 객체 생성과 해제, 소유권 180 | * arc_basic : 객체 생성과 소유, 객체 해제 181 | * scope : 스코프에 의한 소유권 해제와 객체 해제 182 | * collection : 콜렉션에 의한 객체 소유와 해제 183 | - 객체 순환 참조(소유), 약한 참조 184 | * reference_cycle : 강한 순환 참조로 인한 객체가 해제되지 않는 상황 185 | * weak : 객체를 소유하지 않는 약한 참조(weak reference) 186 | * unowned : 객체를 소유하지 않는 약한 참조 중 unowned 187 | 188 | ## 13.TypeCheck 189 | * any : Any, AnyObject 타입. 동적인 타입 변경 190 | * type_check : is를 이용한 타입 체크 191 | * type_cast : as를 이용한 타입 변환 192 | * type_alias : 타입 알리아스 193 | 194 | ## 14.Extension 195 | * extension : 타입 확장 196 | * extension_struct_enum : 구조체와 Enum 확장 197 | * extension_existing_type : 기존 타입 확장(String) 198 | 199 | ## 15.에러 처리(Error Handling) 200 | 201 | - 에러 정의, 에러 다루기 202 | * error : 에러 정의, 에러 발생과 다루기 203 | * error_function : 에러가 발생하는 함수 작성, 호출. 반환값 204 | * error_propagation : 에러 전파 205 | * error_closure : 에러 발생 클로저 사용하기. 206 | * defer : defer를 이용한 예외 상황 마무리 동작 207 | 208 | ## 16.Generics 209 | * generics : 배열과 딕셔너리 타입별 객체 생성과 사용 210 | * custom_type_generics : 제네릭스로 타입 추상화된 함수와 타입 작성하기 211 | 212 | ## 17.Operator 213 | - 연산자 214 | * overloading : 연산지 오버로딩 215 | * equal : 객체 비교 연산자 오버로딩 216 | * custom_operator : 새로운 연산자 선언, 정의 217 | - 첨자 표기법 218 | * subscript : 첨자 표기 219 | 220 | ## 18.접근 조절 221 | * AccessLevel : 커맨드라인 프로젝트 내 프레임워크를 사용한 접근 조절 예제. 동작안하니 코드 작성과 컴파일만 참고. 222 | * AccessLevelApp : iOS 프로젝트 내 프레임워크를 사용한 접근 조절 예제. 동작함. 223 | 224 | ## 19.디자인 패턴 225 | * singleton : 싱글톤 패턴 226 | 227 | ## 20.파운데이션 228 | - NSObject 229 | * nsobject_equal : NSObject와 객체 비교 isEqual(_:) 230 | * nsobject_typecheck : NSObject와 객체 비교 : isKind(of:), isMember(of:) 231 | * selector : Selector 232 | * selector_ambiguous : Selector Ambiguous 에러와 해결 방법 233 | * selector_perform : 셀렉터 동작 검사와 실행 234 | * nsobject_description : 객체 설명 235 | - Protocol 236 | * protocol_optional : 프로토콜 내 선택적 구현 항목 237 | - 데이터 다루기 238 | * type_convert : Foundation Framework 데이터 타입과 Swift 타입 간 변환 239 | - 문자열 240 | * string1, string2 : NSString, String 다루기와 비교 241 | * string_file : 문자열 저장 242 | * string_referenceType : Reference 타입인 NSString 243 | * string_mutable : NSMutableString 244 | - 배열 245 | * array : NSArray, Array 비교, 다루기 246 | * array_file : 배열 파일 저장 247 | * array_mutable : Mutable Array 248 | - 딕셔너리 249 | * dictionary : Dictioanry, NSDictionary 비교, 다루기 250 | * dictionary_file : 딕셔너리 파일 저장 251 | - 날짜와 시간 252 | * date : 날짜, 날짜 포맷터, 칼렌더 다루기 253 | - 파일 다루기 254 | * fm_list : 파일 매니저로 파일 목록 255 | * fm_copyremove : 파일 매니저로 파일 존재 확인/복사/삭제 256 | * fm_read : FileHandler로 파일 내용 읽기/쓰기 257 | - 데이타 258 | * data_base64 : Data를 이용한 Base64 인코딩/디코딩 259 | - 직렬화 260 | * archive1 : NSKeyedArchiver, Unarchiver 261 | * archive2 : Custom Class, NSCoding 262 | - 타이머 263 | * timer : 타이머 예제 264 | - 알림 265 | * notification : 알림 266 | - 멀티쓰레드 267 | * thread1 : Thread를 사용한 멀티 쓰레드 268 | * thread2 : 큐 기반의 멀티 쓰레드 269 | - 네트워크 270 | * url : URL 생성. 정보 얻기 271 | * url_resource_loading 272 | - JSON 273 | * json_parsing -------------------------------------------------------------------------------- /z.ARC/arc_basic.swift: -------------------------------------------------------------------------------- 1 | class MyClass { 2 | deinit { 3 | print("메모리에서 해제") 4 | } 5 | } 6 | 7 | 8 | print("== 객체 생성과 해제 실습") 9 | print(" - 객체 생성") 10 | var obj : MyClass! = MyClass() 11 | 12 | print(" - 소유권 해제") 13 | obj = nil 14 | 15 | 16 | print("== 객체 소유 추가하기") 17 | print(" - 객체 생성") 18 | var obj2 : MyClass! = MyClass() 19 | 20 | print(" - 객체 소유") 21 | var anotherPointer = obj2 22 | 23 | print(" - 소유권 해제") 24 | obj2 = nil 25 | 26 | print("== 실습 종료") 27 | -------------------------------------------------------------------------------- /z.ARC/collection.swift: -------------------------------------------------------------------------------- 1 | class MyClass { 2 | deinit { 3 | print("메모리에서 해제") 4 | } 5 | } 6 | 7 | 8 | print("객체 생성") 9 | var obj : MyClass! = MyClass() 10 | 11 | print("배열에 저장") 12 | var array = [obj] 13 | 14 | print("객체 소유권 해제") 15 | obj = nil 16 | 17 | 18 | print("배열에서 객체 제거") 19 | array.remove(at: 0) 20 | -------------------------------------------------------------------------------- /z.ARC/reference_cycle.swift: -------------------------------------------------------------------------------- 1 | class ClassA { 2 | // ClassB 참조 3 | var objB : ClassB! 4 | 5 | deinit { 6 | print("A객체 해제") 7 | } 8 | } 9 | 10 | class ClassB { 11 | // ClassA 참조 12 | var objA : ClassA! 13 | 14 | deinit { 15 | print("B객체 해제") 16 | } 17 | } 18 | 19 | 20 | print("객체 생성 후 상호 소유") 21 | var a : ClassA! = ClassA() 22 | var b : ClassB! = ClassB() 23 | a.objB = b 24 | b.objA = a 25 | 26 | // 수동으로 상호 소유 관계를 해제하면 객체가 해제된다. 27 | //a.objB = nil 28 | 29 | print("두 객체 소유권 해제") 30 | a = nil 31 | b = nil 32 | -------------------------------------------------------------------------------- /z.ARC/scope.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 변수의 스코프 범위에 의한 소유권 해제 3 | */ 4 | 5 | class MyClass { 6 | deinit { 7 | print("로컬 변수로 선언한 객체 해제") 8 | } 9 | } 10 | 11 | class MyClass2 { 12 | deinit { 13 | print("프로퍼티로 선언한 객체 해제") 14 | } 15 | } 16 | 17 | 18 | class MyApplication { 19 | // 프로퍼티로 선언 20 | var obj : MyClass2 21 | 22 | init() { 23 | obj = MyClass2() 24 | } 25 | 26 | func sayHello() { 27 | let obj2 = MyClass() 28 | print(obj2) // 경고 제거용 29 | print("함수 호출 : Hello World!") 30 | } 31 | } 32 | 33 | var app : MyApplication! = MyApplication() 34 | 35 | app.sayHello() 36 | print("함수 호출 끝") 37 | -------------------------------------------------------------------------------- /z.ARC/unowned.swift: -------------------------------------------------------------------------------- 1 | class Country { 2 | var name : String 3 | 4 | init(name : String) { 5 | self.name = name 6 | } 7 | 8 | deinit { 9 | print("Country 객체 헤제") 10 | } 11 | } 12 | 13 | class Capital { 14 | var name : String 15 | 16 | // 소유하지 않는 포인터. unowned는 옵셔널로 선언할 수 없다. 17 | unowned var country : Country 18 | 19 | init(name : String, country : Country) { 20 | self.name = name 21 | self.country = country 22 | } 23 | 24 | deinit { 25 | print("City 객체 해제") 26 | } 27 | } 28 | 29 | var korea : Country! = Country(name: "Korea") 30 | var seoul : Capital! = Capital(name: "Seoul", country: korea) 31 | 32 | korea = nil 33 | //print(seoul.country) // Error, Dangling Pointer 34 | seoul = nil -------------------------------------------------------------------------------- /z.ARC/weak.swift: -------------------------------------------------------------------------------- 1 | class Person { 2 | var phone : Phone! 3 | deinit { 4 | print("Person 객체 해제") 5 | } 6 | } 7 | 8 | class Phone { 9 | // 소유하지 않는 참조. weak는 옵셔널로만 선언 가능 10 | weak var owner : Person? 11 | deinit { 12 | print("Phone 객체 해제") 13 | } 14 | } 15 | 16 | 17 | var owner : Person! = Person() 18 | var iphone : Phone! = Phone() 19 | 20 | iphone.owner = owner 21 | owner.phone = iphone 22 | 23 | owner = nil 24 | print(iphone.owner) // nil 25 | iphone = nil 26 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevel/AccessLevel.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2C06496F1DB7F2CE001FCA9F /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C06496E1DB7F2CE001FCA9F /* main.swift */; }; 11 | 2C0649761DB7F2DD001FCA9F /* other.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0649751DB7F2DD001FCA9F /* other.swift */; }; 12 | 2C0649801DB7F62E001FCA9F /* InnerFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C06497E1DB7F62E001FCA9F /* InnerFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 2C0649851DB7F648001FCA9F /* framework.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0649841DB7F648001FCA9F /* framework.swift */; }; 14 | 2C06499A1DB7FAD1001FCA9F /* InnerFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C06497C1DB7F62E001FCA9F /* InnerFramework.framework */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXCopyFilesBuildPhase section */ 18 | 2C0649691DB7F2CE001FCA9F /* CopyFiles */ = { 19 | isa = PBXCopyFilesBuildPhase; 20 | buildActionMask = 2147483647; 21 | dstPath = usr/share/man/man1; 22 | dstSubfolderSpec = 16; 23 | files = ( 24 | ); 25 | runOnlyForDeploymentPostprocessing = 1; 26 | }; 27 | /* End PBXCopyFilesBuildPhase section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 2C06496B1DB7F2CE001FCA9F /* AccessLevel */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AccessLevel; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 2C06496E1DB7F2CE001FCA9F /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 32 | 2C0649751DB7F2DD001FCA9F /* other.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = other.swift; sourceTree = ""; }; 33 | 2C06497C1DB7F62E001FCA9F /* InnerFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = InnerFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 2C06497E1DB7F62E001FCA9F /* InnerFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InnerFramework.h; sourceTree = ""; }; 35 | 2C06497F1DB7F62E001FCA9F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 2C0649841DB7F648001FCA9F /* framework.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = framework.swift; sourceTree = ""; }; 37 | /* End PBXFileReference section */ 38 | 39 | /* Begin PBXFrameworksBuildPhase section */ 40 | 2C0649681DB7F2CE001FCA9F /* Frameworks */ = { 41 | isa = PBXFrameworksBuildPhase; 42 | buildActionMask = 2147483647; 43 | files = ( 44 | 2C06499A1DB7FAD1001FCA9F /* InnerFramework.framework in Frameworks */, 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | 2C0649781DB7F62E001FCA9F /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 2C0649621DB7F2CE001FCA9F = { 59 | isa = PBXGroup; 60 | children = ( 61 | 2C06496D1DB7F2CE001FCA9F /* AccessLevel */, 62 | 2C06497D1DB7F62E001FCA9F /* InnerFramework */, 63 | 2C06496C1DB7F2CE001FCA9F /* Products */, 64 | ); 65 | sourceTree = ""; 66 | }; 67 | 2C06496C1DB7F2CE001FCA9F /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 2C06496B1DB7F2CE001FCA9F /* AccessLevel */, 71 | 2C06497C1DB7F62E001FCA9F /* InnerFramework.framework */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 2C06496D1DB7F2CE001FCA9F /* AccessLevel */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 2C06496E1DB7F2CE001FCA9F /* main.swift */, 80 | 2C0649751DB7F2DD001FCA9F /* other.swift */, 81 | ); 82 | path = AccessLevel; 83 | sourceTree = ""; 84 | }; 85 | 2C06497D1DB7F62E001FCA9F /* InnerFramework */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 2C06497E1DB7F62E001FCA9F /* InnerFramework.h */, 89 | 2C06497F1DB7F62E001FCA9F /* Info.plist */, 90 | 2C0649841DB7F648001FCA9F /* framework.swift */, 91 | ); 92 | path = InnerFramework; 93 | sourceTree = ""; 94 | }; 95 | /* End PBXGroup section */ 96 | 97 | /* Begin PBXHeadersBuildPhase section */ 98 | 2C0649791DB7F62E001FCA9F /* Headers */ = { 99 | isa = PBXHeadersBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 2C0649801DB7F62E001FCA9F /* InnerFramework.h in Headers */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXHeadersBuildPhase section */ 107 | 108 | /* Begin PBXNativeTarget section */ 109 | 2C06496A1DB7F2CE001FCA9F /* AccessLevel */ = { 110 | isa = PBXNativeTarget; 111 | buildConfigurationList = 2C0649721DB7F2CF001FCA9F /* Build configuration list for PBXNativeTarget "AccessLevel" */; 112 | buildPhases = ( 113 | 2C0649671DB7F2CE001FCA9F /* Sources */, 114 | 2C0649681DB7F2CE001FCA9F /* Frameworks */, 115 | 2C0649691DB7F2CE001FCA9F /* CopyFiles */, 116 | ); 117 | buildRules = ( 118 | ); 119 | dependencies = ( 120 | ); 121 | name = AccessLevel; 122 | productName = AccessLevel; 123 | productReference = 2C06496B1DB7F2CE001FCA9F /* AccessLevel */; 124 | productType = "com.apple.product-type.tool"; 125 | }; 126 | 2C06497B1DB7F62E001FCA9F /* InnerFramework */ = { 127 | isa = PBXNativeTarget; 128 | buildConfigurationList = 2C0649811DB7F62E001FCA9F /* Build configuration list for PBXNativeTarget "InnerFramework" */; 129 | buildPhases = ( 130 | 2C0649771DB7F62E001FCA9F /* Sources */, 131 | 2C0649781DB7F62E001FCA9F /* Frameworks */, 132 | 2C0649791DB7F62E001FCA9F /* Headers */, 133 | 2C06497A1DB7F62E001FCA9F /* Resources */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = InnerFramework; 140 | productName = InnerFramework; 141 | productReference = 2C06497C1DB7F62E001FCA9F /* InnerFramework.framework */; 142 | productType = "com.apple.product-type.framework"; 143 | }; 144 | /* End PBXNativeTarget section */ 145 | 146 | /* Begin PBXProject section */ 147 | 2C0649631DB7F2CE001FCA9F /* Project object */ = { 148 | isa = PBXProject; 149 | attributes = { 150 | LastSwiftUpdateCheck = 0800; 151 | LastUpgradeCheck = 0800; 152 | ORGANIZATIONNAME = VanillaStep; 153 | TargetAttributes = { 154 | 2C06496A1DB7F2CE001FCA9F = { 155 | CreatedOnToolsVersion = 8.0; 156 | DevelopmentTeam = U83637X5J4; 157 | ProvisioningStyle = Automatic; 158 | }; 159 | 2C06497B1DB7F62E001FCA9F = { 160 | CreatedOnToolsVersion = 8.0; 161 | DevelopmentTeam = U83637X5J4; 162 | LastSwiftMigration = 0800; 163 | ProvisioningStyle = Automatic; 164 | }; 165 | }; 166 | }; 167 | buildConfigurationList = 2C0649661DB7F2CE001FCA9F /* Build configuration list for PBXProject "AccessLevel" */; 168 | compatibilityVersion = "Xcode 3.2"; 169 | developmentRegion = English; 170 | hasScannedForEncodings = 0; 171 | knownRegions = ( 172 | en, 173 | ); 174 | mainGroup = 2C0649621DB7F2CE001FCA9F; 175 | productRefGroup = 2C06496C1DB7F2CE001FCA9F /* Products */; 176 | projectDirPath = ""; 177 | projectRoot = ""; 178 | targets = ( 179 | 2C06496A1DB7F2CE001FCA9F /* AccessLevel */, 180 | 2C06497B1DB7F62E001FCA9F /* InnerFramework */, 181 | ); 182 | }; 183 | /* End PBXProject section */ 184 | 185 | /* Begin PBXResourcesBuildPhase section */ 186 | 2C06497A1DB7F62E001FCA9F /* Resources */ = { 187 | isa = PBXResourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXResourcesBuildPhase section */ 194 | 195 | /* Begin PBXSourcesBuildPhase section */ 196 | 2C0649671DB7F2CE001FCA9F /* Sources */ = { 197 | isa = PBXSourcesBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | 2C06496F1DB7F2CE001FCA9F /* main.swift in Sources */, 201 | 2C0649761DB7F2DD001FCA9F /* other.swift in Sources */, 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | }; 205 | 2C0649771DB7F62E001FCA9F /* Sources */ = { 206 | isa = PBXSourcesBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | 2C0649851DB7F648001FCA9F /* framework.swift in Sources */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | /* End PBXSourcesBuildPhase section */ 214 | 215 | /* Begin XCBuildConfiguration section */ 216 | 2C0649701DB7F2CE001FCA9F /* Debug */ = { 217 | isa = XCBuildConfiguration; 218 | buildSettings = { 219 | ALWAYS_SEARCH_USER_PATHS = NO; 220 | CLANG_ANALYZER_NONNULL = YES; 221 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 222 | CLANG_CXX_LIBRARY = "libc++"; 223 | CLANG_ENABLE_MODULES = YES; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_WARN_BOOL_CONVERSION = YES; 226 | CLANG_WARN_CONSTANT_CONVERSION = YES; 227 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 228 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 229 | CLANG_WARN_EMPTY_BODY = YES; 230 | CLANG_WARN_ENUM_CONVERSION = YES; 231 | CLANG_WARN_INFINITE_RECURSION = YES; 232 | CLANG_WARN_INT_CONVERSION = YES; 233 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 234 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 235 | CLANG_WARN_UNREACHABLE_CODE = YES; 236 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 237 | CODE_SIGN_IDENTITY = "-"; 238 | COPY_PHASE_STRIP = NO; 239 | DEBUG_INFORMATION_FORMAT = dwarf; 240 | ENABLE_STRICT_OBJC_MSGSEND = YES; 241 | ENABLE_TESTABILITY = YES; 242 | GCC_C_LANGUAGE_STANDARD = gnu99; 243 | GCC_DYNAMIC_NO_PIC = NO; 244 | GCC_NO_COMMON_BLOCKS = YES; 245 | GCC_OPTIMIZATION_LEVEL = 0; 246 | GCC_PREPROCESSOR_DEFINITIONS = ( 247 | "DEBUG=1", 248 | "$(inherited)", 249 | ); 250 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 251 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 252 | GCC_WARN_UNDECLARED_SELECTOR = YES; 253 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 254 | GCC_WARN_UNUSED_FUNCTION = YES; 255 | GCC_WARN_UNUSED_VARIABLE = YES; 256 | MACOSX_DEPLOYMENT_TARGET = 10.11; 257 | MTL_ENABLE_DEBUG_INFO = YES; 258 | ONLY_ACTIVE_ARCH = YES; 259 | SDKROOT = macosx; 260 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 261 | }; 262 | name = Debug; 263 | }; 264 | 2C0649711DB7F2CE001FCA9F /* Release */ = { 265 | isa = XCBuildConfiguration; 266 | buildSettings = { 267 | ALWAYS_SEARCH_USER_PATHS = NO; 268 | CLANG_ANALYZER_NONNULL = YES; 269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 270 | CLANG_CXX_LIBRARY = "libc++"; 271 | CLANG_ENABLE_MODULES = YES; 272 | CLANG_ENABLE_OBJC_ARC = YES; 273 | CLANG_WARN_BOOL_CONVERSION = YES; 274 | CLANG_WARN_CONSTANT_CONVERSION = YES; 275 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 276 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 277 | CLANG_WARN_EMPTY_BODY = YES; 278 | CLANG_WARN_ENUM_CONVERSION = YES; 279 | CLANG_WARN_INFINITE_RECURSION = YES; 280 | CLANG_WARN_INT_CONVERSION = YES; 281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 282 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 283 | CLANG_WARN_UNREACHABLE_CODE = YES; 284 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 285 | CODE_SIGN_IDENTITY = "-"; 286 | COPY_PHASE_STRIP = NO; 287 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 288 | ENABLE_NS_ASSERTIONS = NO; 289 | ENABLE_STRICT_OBJC_MSGSEND = YES; 290 | GCC_C_LANGUAGE_STANDARD = gnu99; 291 | GCC_NO_COMMON_BLOCKS = YES; 292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 294 | GCC_WARN_UNDECLARED_SELECTOR = YES; 295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 296 | GCC_WARN_UNUSED_FUNCTION = YES; 297 | GCC_WARN_UNUSED_VARIABLE = YES; 298 | MACOSX_DEPLOYMENT_TARGET = 10.11; 299 | MTL_ENABLE_DEBUG_INFO = NO; 300 | SDKROOT = macosx; 301 | }; 302 | name = Release; 303 | }; 304 | 2C0649731DB7F2CF001FCA9F /* Debug */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | DEVELOPMENT_TEAM = U83637X5J4; 308 | PRODUCT_NAME = "$(TARGET_NAME)"; 309 | SWIFT_VERSION = 3.0; 310 | }; 311 | name = Debug; 312 | }; 313 | 2C0649741DB7F2CF001FCA9F /* Release */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | DEVELOPMENT_TEAM = U83637X5J4; 317 | PRODUCT_NAME = "$(TARGET_NAME)"; 318 | SWIFT_VERSION = 3.0; 319 | }; 320 | name = Release; 321 | }; 322 | 2C0649821DB7F62E001FCA9F /* Debug */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | CLANG_ENABLE_MODULES = YES; 326 | CODE_SIGN_IDENTITY = ""; 327 | COMBINE_HIDPI_IMAGES = YES; 328 | CURRENT_PROJECT_VERSION = 1; 329 | DEFINES_MODULE = YES; 330 | DEVELOPMENT_TEAM = U83637X5J4; 331 | DYLIB_COMPATIBILITY_VERSION = 1; 332 | DYLIB_CURRENT_VERSION = 1; 333 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 334 | FRAMEWORK_VERSION = A; 335 | INFOPLIST_FILE = InnerFramework/Info.plist; 336 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 337 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 338 | PRODUCT_BUNDLE_IDENTIFIER = com.vanillastep.example.InnerFramework; 339 | PRODUCT_NAME = "$(TARGET_NAME)"; 340 | SKIP_INSTALL = YES; 341 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 342 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 343 | SWIFT_VERSION = 3.0; 344 | VERSIONING_SYSTEM = "apple-generic"; 345 | VERSION_INFO_PREFIX = ""; 346 | }; 347 | name = Debug; 348 | }; 349 | 2C0649831DB7F62E001FCA9F /* Release */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | CLANG_ENABLE_MODULES = YES; 353 | CODE_SIGN_IDENTITY = ""; 354 | COMBINE_HIDPI_IMAGES = YES; 355 | CURRENT_PROJECT_VERSION = 1; 356 | DEFINES_MODULE = YES; 357 | DEVELOPMENT_TEAM = U83637X5J4; 358 | DYLIB_COMPATIBILITY_VERSION = 1; 359 | DYLIB_CURRENT_VERSION = 1; 360 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 361 | FRAMEWORK_VERSION = A; 362 | INFOPLIST_FILE = InnerFramework/Info.plist; 363 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 364 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 365 | PRODUCT_BUNDLE_IDENTIFIER = com.vanillastep.example.InnerFramework; 366 | PRODUCT_NAME = "$(TARGET_NAME)"; 367 | SKIP_INSTALL = YES; 368 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 369 | SWIFT_VERSION = 3.0; 370 | VERSIONING_SYSTEM = "apple-generic"; 371 | VERSION_INFO_PREFIX = ""; 372 | }; 373 | name = Release; 374 | }; 375 | /* End XCBuildConfiguration section */ 376 | 377 | /* Begin XCConfigurationList section */ 378 | 2C0649661DB7F2CE001FCA9F /* Build configuration list for PBXProject "AccessLevel" */ = { 379 | isa = XCConfigurationList; 380 | buildConfigurations = ( 381 | 2C0649701DB7F2CE001FCA9F /* Debug */, 382 | 2C0649711DB7F2CE001FCA9F /* Release */, 383 | ); 384 | defaultConfigurationIsVisible = 0; 385 | defaultConfigurationName = Release; 386 | }; 387 | 2C0649721DB7F2CF001FCA9F /* Build configuration list for PBXNativeTarget "AccessLevel" */ = { 388 | isa = XCConfigurationList; 389 | buildConfigurations = ( 390 | 2C0649731DB7F2CF001FCA9F /* Debug */, 391 | 2C0649741DB7F2CF001FCA9F /* Release */, 392 | ); 393 | defaultConfigurationIsVisible = 0; 394 | defaultConfigurationName = Release; 395 | }; 396 | 2C0649811DB7F62E001FCA9F /* Build configuration list for PBXNativeTarget "InnerFramework" */ = { 397 | isa = XCConfigurationList; 398 | buildConfigurations = ( 399 | 2C0649821DB7F62E001FCA9F /* Debug */, 400 | 2C0649831DB7F62E001FCA9F /* Release */, 401 | ); 402 | defaultConfigurationIsVisible = 0; 403 | defaultConfigurationName = Release; 404 | }; 405 | /* End XCConfigurationList section */ 406 | }; 407 | rootObject = 2C0649631DB7F2CE001FCA9F /* Project object */; 408 | } 409 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevel/AccessLevel.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevel/AccessLevel/main.swift: -------------------------------------------------------------------------------- 1 | let obj = PublicClass() 2 | 3 | obj.publicMethod() 4 | obj.internalMethod() 5 | 6 | //obj.fileprivateMethod() // Error 7 | //obj.privateMethod() // Error 8 | 9 | 10 | import InnerFramework 11 | 12 | // internal access level은 외부 모듈에서 접근 불가 13 | //let internalObj = InternalLibClass() 14 | 15 | // public access level 클래스 16 | let publicObj = PublicLibClass() 17 | publicObj.publicMethod() 18 | 19 | // open access level이 아니면 상속 불가 20 | //class ChildPubClass : PublicLibClass { 21 | // 22 | //} 23 | 24 | 25 | // open access level 클래스 26 | let openObj = OpenLibClass() 27 | openObj.openMethod() 28 | openObj.publicMethod() 29 | 30 | // open access level은 상속 가능 31 | class ChildOpenClass : OpenLibClass { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevel/AccessLevel/other.swift: -------------------------------------------------------------------------------- 1 | // 2 | // privateFile.swift 3 | // AccessLevel 4 | // 5 | // Created by wannabewize on 2016. 10. 20.. 6 | // Copyright © 2016년 VanillaStep. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | fileprivate struct FilePrivateStruct { 12 | 13 | fileprivate func filePrivateFunc() { 14 | print("filePrivate function works") 15 | } 16 | 17 | private func privateFunc() { 18 | print("private function works") 19 | } 20 | } 21 | 22 | func testRunner() { 23 | let obj = FilePrivateStruct() 24 | obj.filePrivateFunc() 25 | //obj.privateFunc() // Error 26 | } 27 | 28 | struct InternalStruct { 29 | 30 | fileprivate func filePrivateFunc() { 31 | print("filePrivate function works") 32 | } 33 | 34 | private func privateFunc() { 35 | print("private function works") 36 | } 37 | 38 | func internalFunc() { 39 | print("internal function works") 40 | } 41 | } 42 | 43 | public struct PublicClass { 44 | public func publicMethod() { 45 | print("public method in public class works") 46 | } 47 | 48 | internal func internalMethod() { 49 | print("internal method in public class works") 50 | } 51 | 52 | fileprivate func fileprivateMethod() { 53 | print("fileprivate method in public class works") 54 | } 55 | 56 | private func privateMethod() { 57 | print("private method in public class works") 58 | } 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevel/InnerFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2016년 VanillaStep. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevel/InnerFramework/InnerFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // InnerFramework.h 3 | // InnerFramework 4 | // 5 | // Created by wannabewize on 2016. 10. 20.. 6 | // Copyright © 2016년 VanillaStep. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for InnerFramework. 12 | FOUNDATION_EXPORT double InnerFrameworkVersionNumber; 13 | 14 | //! Project version string for InnerFramework. 15 | FOUNDATION_EXPORT const unsigned char InnerFrameworkVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevel/InnerFramework/framework.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public class PublicLibClass { 4 | public func publicMethod() { 5 | print("public method works") 6 | } 7 | 8 | internal func internalMethod() { 9 | print("internal method works") 10 | } 11 | 12 | // 다른 모듈에서 객체 생성을 하려면 public 이상의 initializer가 필요 13 | public init() { 14 | } 15 | } 16 | 17 | open class OpenLibClass { 18 | open func openMethod() { 19 | print("open method works") 20 | } 21 | 22 | public func publicMethod() { 23 | print("public method works") 24 | } 25 | 26 | public init() { 27 | 28 | } 29 | } 30 | 31 | internal class InternalLibClass { 32 | func internalMethod() { 33 | print("internal method works") 34 | } 35 | 36 | public init() { 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/AccessLevelApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/AccessLevelApp/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | 6 | var window: UIWindow? 7 | 8 | 9 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 10 | // Override point for customization after application launch. 11 | return true 12 | } 13 | 14 | func applicationWillResignActive(_ application: UIApplication) { 15 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 16 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 17 | } 18 | 19 | func applicationDidEnterBackground(_ application: UIApplication) { 20 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 21 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 22 | } 23 | 24 | func applicationWillEnterForeground(_ application: UIApplication) { 25 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 26 | } 27 | 28 | func applicationDidBecomeActive(_ application: UIApplication) { 29 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 30 | } 31 | 32 | func applicationWillTerminate(_ application: UIApplication) { 33 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 34 | } 35 | 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/AccessLevelApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/AccessLevelApp/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/AccessLevelApp/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/AccessLevelApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/AccessLevelApp/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import MyModule 3 | 4 | func doAccessLevelExample() { 5 | 6 | // internal access level은 외부 모듈에서 접근 불가 7 | // let internalObj = InternalLibClass() 8 | 9 | // public access level 클래스 10 | let publicObj = PublicLibClass() 11 | publicObj.publicMethod() 12 | 13 | // open access level이 아니면 상속 불가 14 | // class ChildPubClass : PublicLibClass { 15 | // 16 | // } 17 | 18 | 19 | // open access level 클래스 20 | let openObj = OpenLibClass() 21 | openObj.openMethod() 22 | openObj.publicMethod() 23 | 24 | // open access level은 상속 가능 25 | class ChildOpenClass : OpenLibClass { 26 | 27 | } 28 | } 29 | 30 | class ViewController: UIViewController { 31 | 32 | override func viewDidLoad() { 33 | super.viewDidLoad() 34 | 35 | doAccessLevelExample() 36 | 37 | } 38 | 39 | override func didReceiveMemoryWarning() { 40 | super.didReceiveMemoryWarning() 41 | // Dispose of any resources that can be recreated. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/MyModule/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/MyModule/MyModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyModule.h 3 | // MyModule 4 | // 5 | // Created by wannabewize on 2016. 10. 21.. 6 | // Copyright © 2016년 VanillaStep. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MyModule. 12 | FOUNDATION_EXPORT double MyModuleVersionNumber; 13 | 14 | //! Project version string for MyModule. 15 | FOUNDATION_EXPORT const unsigned char MyModuleVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /z.AccessLevels/AccessLevelApp/MyModule/myModules.swift: -------------------------------------------------------------------------------- 1 | public class PublicLibClass { 2 | public func publicMethod() { 3 | print("public method works") 4 | } 5 | 6 | internal func internalMethod() { 7 | print("internal method works") 8 | } 9 | 10 | // 다른 모듈에서 객체 생성을 하려면 public 이상의 initializer가 필요 11 | public init() { 12 | } 13 | } 14 | 15 | open class OpenLibClass { 16 | open func openMethod() { 17 | print("open method works") 18 | } 19 | 20 | public func publicMethod() { 21 | print("public method works") 22 | } 23 | 24 | public init() { 25 | 26 | } 27 | } 28 | 29 | internal class InternalLibClass { 30 | func internalMethod() { 31 | print("internal method works") 32 | } 33 | 34 | public init() { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /z.DesignPattern/delegate1.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 델리게이트 패턴 구현 3 | */ 4 | import Foundation 5 | 6 | protocol ActionDelegate { 7 | func handleDone() 8 | } 9 | 10 | class Action { 11 | var delegate : ActionDelegate! 12 | 13 | func actionDone() { 14 | // 델리게이트에게 위임 처리 15 | delegate.handleDone() 16 | } 17 | } 18 | 19 | class MyClass : ActionDelegate { 20 | func handleDone() { 21 | print("완료 동작 위임 완료!") 22 | } 23 | } 24 | 25 | 26 | let action = Action() 27 | let obj = MyClass() 28 | action.delegate = obj 29 | 30 | // 액션에서 발생한 동작은 델리게이트에게 위임해서 처리된다. 31 | action.actionDone() -------------------------------------------------------------------------------- /z.DesignPattern/delegate2.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 델리게이트 패턴 구현2 3 | * 선택항목 사용 4 | */ 5 | 6 | import Foundation 7 | 8 | @objc protocol ActionDelegate : class { 9 | func handleDone() 10 | @objc optional func handleCancel() // 선택적 구현 항목 11 | } 12 | 13 | class Action { 14 | weak var delegate : ActionDelegate! 15 | 16 | func actionDone() { 17 | // 델리게이트가 없을 수도 있다. 18 | if delegate != nil { 19 | // 델리게이트 객체가 있으면 위임 처리 20 | delegate.handleDone() 21 | } 22 | else { 23 | print("델리게이트가 없으면 위임하지 않는다. 기본 구현으로 동작") 24 | } 25 | } 26 | 27 | func actionCancel() { 28 | if delegate != nil { 29 | // 옵셔널 항목이므로 옵셔널 타입이다. 30 | delegate.handleCancel?() 31 | } 32 | else { 33 | print("델리게이트가 없으면 위임하지 않는다. 기본 구현으로 동작") 34 | } 35 | } 36 | } 37 | 38 | class MyClass : NSObject, ActionDelegate { 39 | func handleDone() { 40 | print("완료 동작 위임 완료!") 41 | } 42 | 43 | func handleCancel() { 44 | print("취소 동작 위임 완료") 45 | } 46 | } 47 | 48 | let action = Action() 49 | let obj = MyClass() 50 | action.delegate = obj 51 | 52 | action.actionDone() 53 | 54 | // 취소에 대한 동작 구현이 안된 상태에서는 기본 구현으로 동작 55 | action.actionCancel() -------------------------------------------------------------------------------- /z.DesignPattern/singleton.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 싱글톤 패턴 3 | */ 4 | 5 | class MyClass { 6 | static let sharedInstance = MyClass() 7 | 8 | // Initializer로 객체 생성 막기 9 | private init() { 10 | 11 | } 12 | } 13 | 14 | 15 | let obj1 = MyClass.sharedInstance 16 | let obj2 = MyClass.sharedInstance 17 | print("obj === obj2", obj1 === obj2) // true 18 | 19 | 20 | // 싱글톤 방식으로만 객체 생성/얻기 21 | //let obj3 = MyClass() 22 | -------------------------------------------------------------------------------- /z.ErrorHandling/custom_error.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 에러 정의와 발생 시키기 3 | */ 4 | 5 | enum CustomError : Error { 6 | case MyFault 7 | case YourFault 8 | } 9 | 10 | do { 11 | throw CustomError.MyFault 12 | } 13 | catch { 14 | print("에러 발생") 15 | } 16 | 17 | do { 18 | throw CustomError.YourFault 19 | } 20 | catch let error { 21 | print("Error :", error) 22 | } 23 | 24 | do { 25 | throw CustomError.YourFault 26 | } 27 | catch CustomError.MyFault { 28 | print("내탓") 29 | } 30 | catch CustomError.YourFault { 31 | print("남탓") 32 | } 33 | 34 | 35 | struct CustomErrorStruct : Error { 36 | var msg : String! 37 | } 38 | 39 | // 클래스로 에러 정의 40 | class CustomErrorClass : Error { 41 | } 42 | 43 | 44 | do { 45 | let error = CustomErrorStruct(msg:"Oooops!") 46 | throw error 47 | } 48 | catch let error { 49 | print("Error occure") 50 | } 51 | 52 | do { 53 | let error = CustomErrorStruct(msg:"Oooops!") 54 | throw error 55 | } 56 | catch let error where error is CustomErrorStruct { 57 | print("구조체로 작성한 에러 발생") 58 | } 59 | catch let error where error is CustomErrorClass { 60 | print("클래스로 작성한 에러 발생") 61 | } 62 | catch let error { 63 | print("그외 에러 발생", error) 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /z.ErrorHandling/defer.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Clean up. try-catch-"final" 3 | */ 4 | 5 | enum MyError : Error { 6 | case error 7 | } 8 | 9 | func dangerousFunction(_ fire : Bool) throws { 10 | defer { 11 | print("동작 마무리") 12 | } 13 | 14 | if fire { 15 | throw MyError.error 16 | } 17 | } 18 | 19 | // 예외 발생 20 | try? dangerousFunction(true) 21 | 22 | // 예외 발생 안함 23 | try? dangerousFunction(false) -------------------------------------------------------------------------------- /z.ErrorHandling/error_closure.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 에러 발생 클로저 3 | */ 4 | 5 | enum CustomError : Error { 6 | case MyFault 7 | case YourFault 8 | } 9 | 10 | // 예외가 발생하는 함수 11 | func dangerousFunction() throws { 12 | throw CustomError.YourFault 13 | } 14 | 15 | // 예외가 발생하는 함수를 파라미터 선언 16 | func doIt(_ arg : () throws -> () ) { 17 | do { 18 | try arg() 19 | } 20 | catch let error { 21 | print("클로저 실행시 발생한 에러 ", error) 22 | } 23 | } 24 | 25 | doIt(dangerousFunction) 26 | 27 | 28 | // inline 방식 29 | doIt { 30 | throw CustomError.MyFault 31 | } 32 | 33 | 34 | // 예외가 발생하는 함수를 반환 타입으로 35 | func doIt2() -> () throws -> () { 36 | return dangerousFunction 37 | } 38 | 39 | let fn = doIt2() 40 | do { 41 | try fn() 42 | } 43 | catch let error { 44 | print("반환값으로 얻은 클로저에서 발생한 에러 ", error) 45 | } 46 | 47 | // 48 | // 클로저 에러 전파 49 | // 50 | 51 | func doIt3(_ arg : () throws -> () ) rethrows { 52 | try arg() 53 | } 54 | 55 | do { 56 | try doIt3 { 57 | throw CustomError.MyFault 58 | } 59 | } 60 | catch let error { 61 | print("클로저에서 발생한 에러가 전파됨 : ", error) 62 | } 63 | -------------------------------------------------------------------------------- /z.ErrorHandling/error_function.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 에러 발생 가능한 함수 3 | */ 4 | 5 | enum CustomError : Error { 6 | case MyFault 7 | case YourFault 8 | } 9 | 10 | func inputPositive(_ val : Int) throws { 11 | guard val > 0 else { 12 | throw CustomError.YourFault 13 | } 14 | 15 | print("정상 수행") 16 | } 17 | 18 | // throws 함수 실행하기. try 19 | try inputPositive(1) 20 | 21 | // 에러 발생 - 비정상 종료 22 | //try inputPositive(0) 23 | 24 | 25 | // throws 함수의 에러 처리 26 | do { 27 | try inputPositive(-1) 28 | } catch let error { 29 | print("에러 발생. 에러 정보 얻기 : \(error)") 30 | } 31 | 32 | 33 | // 34 | // 반환 타입이 있는 함수 35 | // 36 | 37 | func incresePositive(num : Int) throws -> Int { 38 | guard num > 0 else { 39 | throw CustomError.YourFault 40 | } 41 | return num + 1 42 | } 43 | 44 | do { 45 | let ret = try incresePositive(num: 1) 46 | } 47 | catch let error { 48 | print("Error 발생", error) 49 | } 50 | 51 | let ret1 = try? incresePositive(num: 0) // 옵셔널, nil 52 | print("try? 호출. 에러 발생 : ",ret1) 53 | 54 | 55 | let ret2 = try? incresePositive(num: 1) 56 | print("try? 호출. 에러 발생 안함 : ",ret2) 57 | 58 | let ret3 = try! incresePositive(num: 1) // Non-optional Type 59 | print("try! 호출. 에러 발생 안함 : ", ret3) 60 | 61 | if let ret4 = try? incresePositive(num: 0) { 62 | print("옵셔널 바인딩과 try.") 63 | } 64 | else { 65 | print("옵셔널 바인딩 - 에러 발생") 66 | } -------------------------------------------------------------------------------- /z.ErrorHandling/error_propagation.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 에러 전파 3 | */ 4 | 5 | enum CustomError : Error { 6 | case MyFault 7 | case YourFault 8 | } 9 | 10 | func dangerousFunction() throws { 11 | throw CustomError.YourFault 12 | } 13 | 14 | // 예외 전파 안하기 15 | func doIt() { 16 | do { 17 | try dangerousFunction() 18 | } 19 | catch let error { 20 | print("예외 전파 안하고 함수 내부에서 처리", error) 21 | } 22 | } 23 | doIt() 24 | 25 | 26 | // 함수 내 발생한 에러 전파하기 27 | func doIt2() throws { 28 | try dangerousFunction() 29 | } 30 | 31 | do { 32 | try doIt2() 33 | } 34 | catch let error { 35 | print("함수에서 발생한 에러 전파",error) 36 | } -------------------------------------------------------------------------------- /z.ErrorHandling/use_error_function.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 에러 다루기 3 | // 4 | 5 | import Foundation 6 | 7 | let str = "Hello Swift" 8 | 9 | // 파일로 저장 10 | let filePath = "/Users/wannabewize/Projects/Lecture/Swift-Samples/Sandbox/str.txt" 11 | // str.write(toFile: filePath, atomically: true, encoding: String.Encoding.utf8) 12 | 13 | // try를 이용한 호출 14 | try str.write(toFile: filePath, atomically: true, encoding: .utf8) 15 | 16 | 17 | // 18 | // 잘못된 경로로 에러가 발생 19 | let wrongFilePath = "/Users/wannabewize/Projects/Lecture/Swift-Samples/Sandbox/" 20 | //try str.write(toFile: wrongFilePath, atomically: true, encoding: .utf8) 21 | 22 | // 잘못된 경로로 에러가 발생 - do-catch로 에러 처리 23 | do { 24 | try str.write(toFile: wrongFilePath, atomically: true, encoding: .utf8) 25 | } 26 | catch { 27 | print("에러 발생") 28 | } 29 | 30 | // 잘못된 경로로 에러가 발생 - do-catch로 에러 처리 31 | do { 32 | try str.write(toFile: wrongFilePath, atomically: true, encoding: .utf8) 33 | } 34 | catch let error { 35 | print("에러 발생 ", error) 36 | } 37 | 38 | 39 | // 반환값이 있는 메소드 호출 40 | let str2 = try String(contentsOfFile: filePath) 41 | print(str2) 42 | 43 | 44 | // 반환값이 있는 메소드에서 발생하는 에러 다루기 45 | do { 46 | let str3 = try String(contentsOfFile: wrongFilePath) 47 | } 48 | catch let error { 49 | print("파일 읽기 에러", error) 50 | } 51 | 52 | // try?를 이용해서 반환값이 있는 메소드에서 발생하는 에러 다루기 53 | let str4 = try? String(contentsOfFile: wrongFilePath) 54 | if str4 == nil { 55 | print("파일 읽기 에러 발생") 56 | } 57 | 58 | // 에러 발생 - 애플리케이션 크래쉬 59 | //let str5 = try! String(contentsOfFile: wrongFilePath) 60 | //print(str5) 61 | 62 | -------------------------------------------------------------------------------- /z.Extension/extension.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 확장 3 | */ 4 | 5 | class Dog { 6 | func eat() { 7 | print("먹기") 8 | } 9 | 10 | init() {} 11 | } 12 | 13 | // extension에서 메소드 작성 14 | extension Dog { 15 | func bike() { 16 | print("멍멍멍") 17 | } 18 | 19 | // extension은 재정의가 안된다. 20 | // func eat() { print("냠냠냠") } // Error. 21 | 22 | static func hasTail() -> Bool { 23 | return true 24 | } 25 | } 26 | 27 | var doggy = Dog() 28 | doggy.eat() 29 | // extension에 있는 메소드 호출 30 | doggy.bike() 31 | 32 | // 타입 메소드 33 | print("개는 꼬리가 있다? : ", Dog.hasTail()) 34 | 35 | 36 | // 37 | // 프로토콜 추가 38 | // 39 | 40 | extension Dog { 41 | // 저장 프로퍼티는 불가 42 | // var color : String! 43 | 44 | // 계산 프로퍼티는 가능 45 | var everageLife : Int! { return 15 } 46 | 47 | } 48 | 49 | // 50 | // Initializer 추가 51 | // 52 | extension Dog { 53 | convenience init(name : String) { 54 | // 원 클래스의 Designated Initializer로 Initializer 위임 55 | self.init() 56 | } 57 | 58 | // Designated Initializer는 불가능 59 | // init(anyVal : Int) {} 60 | } 61 | 62 | let obj = Dog(name : "멍멍이") 63 | 64 | // 65 | // 프로토콜 채택 66 | // 67 | 68 | protocol Running { 69 | func run() 70 | } 71 | 72 | // Extension에서 프로토콜 채택 73 | extension Dog : Running { 74 | func run() { 75 | print("뛰기") 76 | } 77 | } 78 | 79 | doggy.run() -------------------------------------------------------------------------------- /z.Extension/extension_existing_type.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 기존 타입 확장 3 | // 4 | 5 | import Foundation 6 | 7 | extension String { 8 | static func randomNum() -> String { 9 | return String(arc4random()) 10 | } 11 | } 12 | 13 | let randomStr = String.randomNum() 14 | print("Random NumStr1 : ", randomStr) 15 | print("Random NumStr2 : ", String.randomNum()) 16 | -------------------------------------------------------------------------------- /z.Extension/extension_struct_enum.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 구조체, Enum extension 3 | // 4 | import Foundation 5 | 6 | 7 | struct Cat {} 8 | 9 | extension Cat { 10 | // 계산 프로퍼티 11 | var averageLife : Int { return 10 } 12 | 13 | // 메소드 14 | func jump() { 15 | print("점프") 16 | } 17 | } 18 | 19 | let kitty = Cat() 20 | kitty.jump() 21 | print(kitty.averageLife) 22 | 23 | // 24 | // Enum extension 25 | // 26 | enum Favorite : Int { 27 | case Movie 28 | case Drive 29 | case Cycle 30 | } 31 | 32 | extension Favorite { 33 | // 타입 계산 프로퍼티 34 | static var random : Favorite { 35 | let r = Int(arc4random_uniform(3)) // 0~2 난수 36 | return Favorite(rawValue: r)! 37 | } 38 | } 39 | 40 | let randomFavorite = Favorite.random 41 | print("Random Favorite : ", randomFavorite.rawValue) -------------------------------------------------------------------------------- /z.Foundation/JsonParsing/JsonParsing.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2CE469301DB8A6FA00F58E1C /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE4692F1DB8A6FA00F58E1C /* main.swift */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 2CE4692A1DB8A6FA00F58E1C /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = /usr/share/man/man1/; 18 | dstSubfolderSpec = 0; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 1; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 2CE4692C1DB8A6FA00F58E1C /* JsonParsing */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JsonParsing; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 2CE4692F1DB8A6FA00F58E1C /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 28 | 2CE469361DB8A70C00F58E1C /* device.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = device.json; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 2CE469291DB8A6FA00F58E1C /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 2CE469231DB8A6FA00F58E1C = { 43 | isa = PBXGroup; 44 | children = ( 45 | 2CE4692E1DB8A6FA00F58E1C /* JsonParsing */, 46 | 2CE4692D1DB8A6FA00F58E1C /* Products */, 47 | ); 48 | sourceTree = ""; 49 | }; 50 | 2CE4692D1DB8A6FA00F58E1C /* Products */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 2CE4692C1DB8A6FA00F58E1C /* JsonParsing */, 54 | ); 55 | name = Products; 56 | sourceTree = ""; 57 | }; 58 | 2CE4692E1DB8A6FA00F58E1C /* JsonParsing */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 2CE4692F1DB8A6FA00F58E1C /* main.swift */, 62 | 2CE469361DB8A70C00F58E1C /* device.json */, 63 | ); 64 | path = JsonParsing; 65 | sourceTree = ""; 66 | }; 67 | /* End PBXGroup section */ 68 | 69 | /* Begin PBXNativeTarget section */ 70 | 2CE4692B1DB8A6FA00F58E1C /* JsonParsing */ = { 71 | isa = PBXNativeTarget; 72 | buildConfigurationList = 2CE469331DB8A6FA00F58E1C /* Build configuration list for PBXNativeTarget "JsonParsing" */; 73 | buildPhases = ( 74 | 2CE469281DB8A6FA00F58E1C /* Sources */, 75 | 2CE469291DB8A6FA00F58E1C /* Frameworks */, 76 | 2CE4692A1DB8A6FA00F58E1C /* CopyFiles */, 77 | ); 78 | buildRules = ( 79 | ); 80 | dependencies = ( 81 | ); 82 | name = JsonParsing; 83 | productName = JsonParsing; 84 | productReference = 2CE4692C1DB8A6FA00F58E1C /* JsonParsing */; 85 | productType = "com.apple.product-type.tool"; 86 | }; 87 | /* End PBXNativeTarget section */ 88 | 89 | /* Begin PBXProject section */ 90 | 2CE469241DB8A6FA00F58E1C /* Project object */ = { 91 | isa = PBXProject; 92 | attributes = { 93 | LastSwiftUpdateCheck = 0800; 94 | LastUpgradeCheck = 0800; 95 | ORGANIZATIONNAME = VanillaStep; 96 | TargetAttributes = { 97 | 2CE4692B1DB8A6FA00F58E1C = { 98 | CreatedOnToolsVersion = 8.0; 99 | DevelopmentTeam = U83637X5J4; 100 | ProvisioningStyle = Automatic; 101 | }; 102 | }; 103 | }; 104 | buildConfigurationList = 2CE469271DB8A6FA00F58E1C /* Build configuration list for PBXProject "JsonParsing" */; 105 | compatibilityVersion = "Xcode 3.2"; 106 | developmentRegion = English; 107 | hasScannedForEncodings = 0; 108 | knownRegions = ( 109 | en, 110 | ); 111 | mainGroup = 2CE469231DB8A6FA00F58E1C; 112 | productRefGroup = 2CE4692D1DB8A6FA00F58E1C /* Products */; 113 | projectDirPath = ""; 114 | projectRoot = ""; 115 | targets = ( 116 | 2CE4692B1DB8A6FA00F58E1C /* JsonParsing */, 117 | ); 118 | }; 119 | /* End PBXProject section */ 120 | 121 | /* Begin PBXSourcesBuildPhase section */ 122 | 2CE469281DB8A6FA00F58E1C /* Sources */ = { 123 | isa = PBXSourcesBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | 2CE469301DB8A6FA00F58E1C /* main.swift in Sources */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXSourcesBuildPhase section */ 131 | 132 | /* Begin XCBuildConfiguration section */ 133 | 2CE469311DB8A6FA00F58E1C /* Debug */ = { 134 | isa = XCBuildConfiguration; 135 | buildSettings = { 136 | ALWAYS_SEARCH_USER_PATHS = NO; 137 | CLANG_ANALYZER_NONNULL = YES; 138 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 139 | CLANG_CXX_LIBRARY = "libc++"; 140 | CLANG_ENABLE_MODULES = YES; 141 | CLANG_ENABLE_OBJC_ARC = YES; 142 | CLANG_WARN_BOOL_CONVERSION = YES; 143 | CLANG_WARN_CONSTANT_CONVERSION = YES; 144 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 145 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 146 | CLANG_WARN_EMPTY_BODY = YES; 147 | CLANG_WARN_ENUM_CONVERSION = YES; 148 | CLANG_WARN_INFINITE_RECURSION = YES; 149 | CLANG_WARN_INT_CONVERSION = YES; 150 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 151 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 152 | CLANG_WARN_UNREACHABLE_CODE = YES; 153 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 154 | CODE_SIGN_IDENTITY = "-"; 155 | COPY_PHASE_STRIP = NO; 156 | DEBUG_INFORMATION_FORMAT = dwarf; 157 | ENABLE_STRICT_OBJC_MSGSEND = YES; 158 | ENABLE_TESTABILITY = YES; 159 | GCC_C_LANGUAGE_STANDARD = gnu99; 160 | GCC_DYNAMIC_NO_PIC = NO; 161 | GCC_NO_COMMON_BLOCKS = YES; 162 | GCC_OPTIMIZATION_LEVEL = 0; 163 | GCC_PREPROCESSOR_DEFINITIONS = ( 164 | "DEBUG=1", 165 | "$(inherited)", 166 | ); 167 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 168 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 169 | GCC_WARN_UNDECLARED_SELECTOR = YES; 170 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 171 | GCC_WARN_UNUSED_FUNCTION = YES; 172 | GCC_WARN_UNUSED_VARIABLE = YES; 173 | MACOSX_DEPLOYMENT_TARGET = 10.11; 174 | MTL_ENABLE_DEBUG_INFO = YES; 175 | ONLY_ACTIVE_ARCH = YES; 176 | SDKROOT = macosx; 177 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 178 | }; 179 | name = Debug; 180 | }; 181 | 2CE469321DB8A6FA00F58E1C /* Release */ = { 182 | isa = XCBuildConfiguration; 183 | buildSettings = { 184 | ALWAYS_SEARCH_USER_PATHS = NO; 185 | CLANG_ANALYZER_NONNULL = YES; 186 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 187 | CLANG_CXX_LIBRARY = "libc++"; 188 | CLANG_ENABLE_MODULES = YES; 189 | CLANG_ENABLE_OBJC_ARC = YES; 190 | CLANG_WARN_BOOL_CONVERSION = YES; 191 | CLANG_WARN_CONSTANT_CONVERSION = YES; 192 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 193 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 194 | CLANG_WARN_EMPTY_BODY = YES; 195 | CLANG_WARN_ENUM_CONVERSION = YES; 196 | CLANG_WARN_INFINITE_RECURSION = YES; 197 | CLANG_WARN_INT_CONVERSION = YES; 198 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 199 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 200 | CLANG_WARN_UNREACHABLE_CODE = YES; 201 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 202 | CODE_SIGN_IDENTITY = "-"; 203 | COPY_PHASE_STRIP = NO; 204 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 205 | ENABLE_NS_ASSERTIONS = NO; 206 | ENABLE_STRICT_OBJC_MSGSEND = YES; 207 | GCC_C_LANGUAGE_STANDARD = gnu99; 208 | GCC_NO_COMMON_BLOCKS = YES; 209 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 210 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 211 | GCC_WARN_UNDECLARED_SELECTOR = YES; 212 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 213 | GCC_WARN_UNUSED_FUNCTION = YES; 214 | GCC_WARN_UNUSED_VARIABLE = YES; 215 | MACOSX_DEPLOYMENT_TARGET = 10.11; 216 | MTL_ENABLE_DEBUG_INFO = NO; 217 | SDKROOT = macosx; 218 | }; 219 | name = Release; 220 | }; 221 | 2CE469341DB8A6FA00F58E1C /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | DEVELOPMENT_TEAM = U83637X5J4; 225 | PRODUCT_NAME = "$(TARGET_NAME)"; 226 | SWIFT_VERSION = 3.0; 227 | }; 228 | name = Debug; 229 | }; 230 | 2CE469351DB8A6FA00F58E1C /* Release */ = { 231 | isa = XCBuildConfiguration; 232 | buildSettings = { 233 | DEVELOPMENT_TEAM = U83637X5J4; 234 | PRODUCT_NAME = "$(TARGET_NAME)"; 235 | SWIFT_VERSION = 3.0; 236 | }; 237 | name = Release; 238 | }; 239 | /* End XCBuildConfiguration section */ 240 | 241 | /* Begin XCConfigurationList section */ 242 | 2CE469271DB8A6FA00F58E1C /* Build configuration list for PBXProject "JsonParsing" */ = { 243 | isa = XCConfigurationList; 244 | buildConfigurations = ( 245 | 2CE469311DB8A6FA00F58E1C /* Debug */, 246 | 2CE469321DB8A6FA00F58E1C /* Release */, 247 | ); 248 | defaultConfigurationIsVisible = 0; 249 | defaultConfigurationName = Release; 250 | }; 251 | 2CE469331DB8A6FA00F58E1C /* Build configuration list for PBXNativeTarget "JsonParsing" */ = { 252 | isa = XCConfigurationList; 253 | buildConfigurations = ( 254 | 2CE469341DB8A6FA00F58E1C /* Debug */, 255 | 2CE469351DB8A6FA00F58E1C /* Release */, 256 | ); 257 | defaultConfigurationIsVisible = 0; 258 | }; 259 | /* End XCConfigurationList section */ 260 | }; 261 | rootObject = 2CE469241DB8A6FA00F58E1C /* Project object */; 262 | } 263 | -------------------------------------------------------------------------------- /z.Foundation/JsonParsing/JsonParsing.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /z.Foundation/JsonParsing/JsonParsing/device.json: -------------------------------------------------------------------------------- 1 | { 2 | "device": 3 | [ 4 | { 5 | "name": "iPhone5s", 6 | "spec": { 7 | "screen": 4, 8 | "cpu": "a7" 9 | } 10 | }, 11 | { 12 | "name": "iPad Air", 13 | "spec": { 14 | "screen": 9.8, 15 | "cpu": "a7" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /z.Foundation/JsonParsing/JsonParsing/main.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // 콘솔에서 동작시키는 경우, 경로 설정이 잘 된다. 4 | let url = URL(fileURLWithPath: "device.json") 5 | 6 | // 파일 존재 확인 7 | let fm = FileManager.default 8 | if !fm.fileExists(atPath: url.path) { 9 | print("JSON 파일 접근 안됨 : ", url.path) 10 | exit(1) // program exit 11 | } 12 | 13 | do { 14 | let data = try Data(contentsOf: url) 15 | let result = try JSONSerialization.jsonObject(with: data, options: []) 16 | 17 | if let root = result as? [String: Any], 18 | let devices = root["device"] as? [Any], 19 | let iPhone7 = devices[0] as? [String:Any] { 20 | 21 | print("iPhone7 : ", iPhone7) 22 | if let spec = iPhone7["spec"] as? [String:Any], 23 | let cpu = spec["cpu"] as? String { 24 | print("iPhone7's cpu is", cpu) 25 | } 26 | } 27 | } 28 | catch let error { 29 | print("Error : ", error.localizedDescription) 30 | } 31 | 32 | 33 | // 참고 : https://developer.apple.com/swift/blog/?id=37 34 | -------------------------------------------------------------------------------- /z.Foundation/archive1.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | // Data로 직렬화 5 | let data = NSKeyedArchiver.archivedData(withRootObject: "String Data") 6 | // NSData에서 읽어오기 7 | if let str = NSKeyedUnarchiver.unarchiveObject(with: data) as? String { 8 | print("NSData에서 복원 : \(str)") 9 | } 10 | 11 | // 파일로 저장 12 | let filePath = "/Users/wannabewize/Documents/data.dat" 13 | let ret = NSKeyedArchiver.archiveRootObject("String Data", toFile: filePath) 14 | 15 | // 파일에서 읽어오기 16 | if let str = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? String { 17 | print("파일에서 복원 : \(str)") 18 | } 19 | else { 20 | print("파일 복원 실패") 21 | } 22 | 23 | 24 | // 바이너리 데이타를 저장할 NSMutableData 객체 25 | var mdata = NSMutableData() 26 | // 데이터를 인코딩하는 아카이버 27 | var archiver = NSKeyedArchiver(forWritingWith: mdata) 28 | 29 | archiver.encode(true, forKey: "BoolData") 30 | archiver.encode(77, forKey: "IntData") 31 | archiver.encode("StringValue", forKey: "StrData") 32 | archiver.finishEncoding() 33 | 34 | // 길이 35 | print("data size \(mdata.length)") 36 | 37 | // NSData에서 복원 38 | var unarchiver = NSKeyedUnarchiver(forReadingWith: mdata as Data) 39 | let boolData = unarchiver.decodeBool(forKey:"BoolData") 40 | let intData = unarchiver.decodeInteger(forKey:"IntData") 41 | let strData = unarchiver.decodeObject(forKey:"StrData") as! String 42 | 43 | print("Bool \(boolData) - Int \(intData) - String : \(strData)") -------------------------------------------------------------------------------- /z.Foundation/archive2.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | // NSObject의 자식 클래스, NSCoding 프로토콜 채택 5 | class Person : NSObject, NSCoding { 6 | var name : String 7 | var birthYear : Int 8 | 9 | init(name : String, birthYear : Int) { 10 | self.name = name 11 | self.birthYear = birthYear 12 | } 13 | 14 | // 객체 프로퍼티 인코딩 15 | func encode(with aCoder: NSCoder) { 16 | aCoder.encode(name, forKey: "Name") 17 | aCoder.encode(birthYear, forKey: "Year") 18 | } 19 | 20 | // 객체 프로퍼티 디코딩 21 | required init(coder aDecoder: NSCoder) { 22 | name = aDecoder.decodeObject(forKey:"Name") as! String 23 | birthYear = aDecoder.decodeInteger(forKey:"Year") 24 | } 25 | } 26 | 27 | 28 | // 저장 29 | var obj = Person(name: "태연", birthYear: 1989) 30 | 31 | // 파일로 아카이빙 32 | let filePath = "/Users/wannabewize/Documents/data.dat" 33 | let ret = NSKeyedArchiver.archiveRootObject(obj, toFile: filePath) 34 | 35 | // 복원 36 | if let obj = NSKeyedUnarchiver.unarchiveObject(withFile:filePath) as? Person { 37 | print("name : \(obj.name) - birthYear : \(obj.birthYear)") 38 | } 39 | 40 | 41 | class Actor : Person { 42 | var filmography : [String]? 43 | override func encode(with aCoder: NSCoder) { 44 | aCoder.encode(filmography, forKey: "Filmography") 45 | super.encode(with: aCoder) 46 | } 47 | required init(coder aDecoder: NSCoder) { 48 | self.filmography = aDecoder.decodeObject(forKey: "Filmography") as? [String] 49 | super.init(coder: aDecoder) 50 | } 51 | override init(name : String, birthYear : Int) { 52 | super.init(name: name, birthYear: birthYear) 53 | } 54 | } 55 | 56 | 57 | // 객체 58 | var actor = Actor(name: "스칼렛 요한슨", birthYear: 1984) 59 | actor.filmography = ["루시", "어밴져스"] 60 | 61 | // 인코딩 62 | let dataActor = NSKeyedArchiver.archivedData(withRootObject:actor) 63 | 64 | // 디코딩 65 | if let obj = NSKeyedUnarchiver.unarchiveObject(with: dataActor) as? Actor { 66 | print("actor2 name : \(obj.name) birthYear : \(obj.birthYear) filmography : \(obj.filmography)") 67 | } 68 | -------------------------------------------------------------------------------- /z.Foundation/array.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | // Swift 배열 5 | let swiftArray1 = ["A", "B", "C"] // Swift 배열 : [String] 6 | let swiftArray2 : [Any] = ["A", "B", 3] // Swift 배열 : [NSObject] 7 | 8 | // NSArray 9 | let nsArray1 : NSArray = ["a", "b", "c"] // NSArray 10 | let nsArray2 = NSArray(objects: 1, 2, 3) // NSArray 11 | 12 | print(swiftArray1.count) 13 | print(nsArray1.count) 14 | 15 | 16 | // 17 | // 원소 접근 18 | // 19 | 20 | let item1 = swiftArray1[0] 21 | print(item1) // String 타입 22 | 23 | let item2 = nsArray1[0] 24 | print(item2, type(of:item2)) // AnyObject 타입 25 | let str = item2 as! String 26 | 27 | let item3 = nsArray2.object(at: 1) 28 | print(item3, type(of:item3)) // AnyObject 타입 29 | 30 | let strArray : NSArray = ["56", "1234", "7", "890"] 31 | 32 | 33 | let sorted = strArray.sortedArray(comparator: { (a : Any, b: Any) -> ComparisonResult in 34 | let str1 = a as! String 35 | let str2 = b as! String 36 | return str1.compare(str2) 37 | }) 38 | 39 | 40 | let numArray = strArray.sortedArray(comparator:{ 41 | let str1 = $0 as! String 42 | let str2 = $1 as! String 43 | // 숫자로 비교 44 | return str1.compare(str2, options: .numeric) 45 | }) 46 | -------------------------------------------------------------------------------- /z.Foundation/array_file.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 배열 저장 3 | */ 4 | 5 | import Foundation 6 | 7 | let array1 : NSArray = ["A", "B", 3] 8 | let path = "/Users/wannabewize/Documents/array.plist" 9 | 10 | let result = array1.write(toFile:path, atomically:true) 11 | print("배열 저장 성공 : \(result)") 12 | 13 | // 파일에서 읽기 14 | let array2 = NSArray(contentsOfFile:path) 15 | print("array from file : \(array2))") 16 | 17 | 18 | // 19 | // Swift Array 저장 -> NSArray로 타입 캐스팅 20 | // 21 | 22 | let array3 = [1, 2, 3] 23 | let path2 = "/Users/wannabewize/Documents/array2.plist" 24 | 25 | let array4 : NSArray = array3 as NSArray 26 | array4.write(toFile: path2, atomically: true) 27 | 28 | let array5 = NSArray(contentsOfFile: path2) 29 | print(array5) 30 | -------------------------------------------------------------------------------- /z.Foundation/array_mutable.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | var marray = NSMutableArray() 4 | 5 | marray.add(2) // 2 6 | marray.insert("1", at: 0) // 1, 2 7 | marray.addObjects(from: [3,4]) // 1,2,3,4 8 | marray.removeObject(at: 1) // 1,3,4 9 | -------------------------------------------------------------------------------- /z.Foundation/data_base64.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Data를 이용한 Base64 인코딩/디코딩 3 | */ 4 | 5 | import Foundation 6 | 7 | let str = "Hello Swift" 8 | 9 | // Base64 Encoding 10 | if let data = str.data(using: .utf8) { 11 | let base64Str = data.base64EncodedString() 12 | print("base64 : ",base64Str) 13 | } 14 | 15 | 16 | // Base64 Decoding 17 | let encoded = "SGVsbG8gU3dpZnQ=" 18 | if let base64Data = Data(base64Encoded: encoded), 19 | let decoded = String(data: base64Data, encoding: .utf8) { 20 | 21 | print("decoded : ", decoded) 22 | } 23 | -------------------------------------------------------------------------------- /z.Foundation/date.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // 4 | // 날짜 객체, 타임 인터벌 5 | // 6 | 7 | let now = Date() // 현재 시각 객체 8 | print("now : ", now) 9 | let yesterday = Date(timeIntervalSinceNow: (-60*60*24)) // 어제 10 | print("yesterday : ", yesterday) 11 | let tomorrow = now.addingTimeInterval(60 * 60 * 24) // 내일 12 | print("tomorrow : ", tomorrow) 13 | 14 | let compare : ComparisonResult = now.compare(yesterday) // OrderedDescending 15 | print("now compare yesterday : ", compare.rawValue) 16 | 17 | 18 | 19 | let days = floor(yesterday.timeIntervalSince(tomorrow)) / (24*60*60) 20 | print("어제와 내일 사이 : ", days) 21 | let minute = ceil(tomorrow.timeIntervalSinceNow) / 60 // 1440 minutes 22 | print("내일까지 : ", minute) 23 | 24 | 25 | // 26 | // 날짜 포맷 27 | // 28 | 29 | let formatter = DateFormatter() 30 | formatter.timeStyle = .short 31 | // 시간 문자열 ShortStyle 로 얻기 32 | let timeStr = formatter.string(from:now) 33 | 34 | let customFormatter = DateFormatter() 35 | customFormatter.dateFormat = "yyyy/MM/dd" 36 | 37 | // 날짜 객체에서 문자열 얻기 38 | let tomorrowStr = customFormatter.string(from:tomorrow) 39 | print("내일 : ", tomorrowStr) 40 | 41 | // 문자열에서 날짜 객체 얻기 42 | let date = customFormatter.date(from:"2016/12/25")! 43 | print(date) 44 | 45 | 46 | // 47 | // 칼렌더 48 | // 49 | 50 | let calendar = Calendar.current 51 | 52 | 53 | // 오늘 날짜 정보 얻기 54 | 55 | let weekOfYear = calendar.component(.weekOfYear, from: now) 56 | let weekOfMonth = calendar.component(.weekOfMonth, from: now) 57 | 58 | // 칼렌더에서 요일과 월 59 | let month = calendar.component(.month, from: now) 60 | let weekday = calendar.component(.weekday, from: now) 61 | 62 | // 월은 1부터 시작 63 | let monthStr = calendar.standaloneMonthSymbols[month-1] 64 | print("월 이름 : ", monthStr) 65 | // 요일은 1부터 시작 66 | let weekdayStr = calendar.standaloneWeekdaySymbols[(weekday-1)] 67 | print("요일 : ", weekdayStr) 68 | 69 | 70 | // 데이트 컴포넌트 71 | var component = DateComponents() 72 | component.year = 2016 // 2016년 73 | component.weekOfYear = 30 // 30번째 주 74 | component.weekday = 1 // 일요일 75 | 76 | 77 | // 데이터 포매터에서 날짜 객체 생성 78 | if let date = calendar.date(from: component) { 79 | // 데이터 포매터 80 | let formatter = DateFormatter() 81 | formatter.dateFormat = "yyyy/MM/dd" 82 | 83 | let dateStr = formatter.string(from:date) // 2016/07/17 84 | print("2016년 30번째주 일요일 : ", dateStr) 85 | } 86 | 87 | let what : Set = [.month, .day, .weekday] // 배열에서 Set 생성 88 | let component2 = calendar.dateComponents(what, from: now) 89 | 90 | print("월 : ", component2.month) // 월 91 | print("일 : ", component2.day) // 일 92 | 93 | -------------------------------------------------------------------------------- /z.Foundation/dictionary.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | var swiftDic = ["Key1":"Value1", "Key2":"Value2"] 4 | var nsDic : NSDictionary = [1 : "one", 2 : "two"] 5 | // Any 타입이므로 각 원소 별 타입을 다르게 할 수 있다. 6 | let nsDic2 = NSDictionary(dictionaryLiteral: ("One", 1), (2, "Two"), (3, 3)) 7 | print(nsDic2) 8 | 9 | let dic : NSDictionary = [1 : "January", 2 : "Febrary", 3 : "March", 4 : "April"] 10 | 11 | 12 | let item1 = dic[1] 13 | let item2 = dic.object(forKey:2) 14 | 15 | if let value = dic[5] { 16 | print("Key 5 : Value \(value)") 17 | } 18 | else { 19 | print("없다.") 20 | } 21 | 22 | 23 | 24 | var mDic = NSMutableDictionary() 25 | // 추가하기 26 | mDic.setObject("Value1", forKey: "Key1" as NSString) 27 | 28 | mDic.setObject(2, forKey: "Key2" as NSString) 29 | // 덮어쓰기 30 | mDic.setObject([1,2,3], forKey: "Key2" as NSString) 31 | 32 | // 첨자로 삭제 33 | mDic["Key1"] = nil 34 | 35 | // 첨자로 변경 36 | mDic["Key2"] = "Value2" 37 | 38 | // 첨자로 추가 39 | mDic["Key3"] = "Three" 40 | print(mDic) 41 | 42 | -------------------------------------------------------------------------------- /z.Foundation/dictionary_file.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | let path = "/Users/wannabewize/Documents/dictionary.plist" 4 | 5 | // NSDictionary의 키가 원시 타입이면 에러는 안나지만 실제 저장 안됨 6 | let dic : NSDictionary = ["January":1, "Febrary":2, "March":3, "April":4] 7 | let ret = dic.write(toFile:path, atomically: true) 8 | if ret { 9 | print("파일 저장 성공") 10 | } 11 | else { 12 | print("파일 저장 실패") 13 | } 14 | 15 | let dic2 = NSDictionary(contentsOfFile: path) 16 | print(dic2) 17 | 18 | 19 | let path2 = "/Users/wannabewize/Documents/dictionary2.plist" 20 | 21 | let dic3 = ["일":"one", "이":"two", "삼":"three"] 22 | 23 | let dic4 = dic3 as NSDictionary 24 | let ret2 = dic4.write(toFile: path2, atomically: true) 25 | if ret { 26 | print("파일 저장 성공") 27 | } 28 | else { 29 | print("파일 저장 실패") 30 | } 31 | 32 | let dic5 = NSDictionary(contentsOfFile: path2) 33 | print(dic5) -------------------------------------------------------------------------------- /z.Foundation/fm_copyremove.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | let fm = FileManager.default 4 | 5 | let originPath = "/Users/wannabewize/Documents/str.txt" 6 | 7 | if fm.fileExists(atPath:originPath) { 8 | print("파일 존재") 9 | let copyPath = "/Users/wannabewize/Documents/str2.txt" 10 | 11 | // 파일 복사 12 | do { 13 | try fm.copyItem(atPath:originPath, toPath: copyPath) 14 | print("파일 복사 성공") 15 | } 16 | catch let error { 17 | print("파일 복사 실패 : \(error)") 18 | } 19 | 20 | do { 21 | try fm.removeItem(atPath:copyPath) 22 | print("파일 삭제 성공") 23 | } 24 | catch let error { 25 | print("파일 삭제 실패 : \(error)") 26 | } 27 | } 28 | else { 29 | print("파일 없음") 30 | } 31 | -------------------------------------------------------------------------------- /z.Foundation/fm_list.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | let dirPath = "/Users/wannabewize/Projects" 4 | 5 | let fm = FileManager.default 6 | 7 | // try? : 에러가 발생하면 nil 반환. 동작 성공하면 셔널 반환 8 | let contentsOfDir = try? fm.contentsOfDirectory(atPath: dirPath) 9 | 10 | if let fileList = contentsOfDir { 11 | print("file list in \(dirPath)") 12 | for file in fileList { 13 | print("\(file)") 14 | } 15 | } 16 | else { 17 | print("에러") 18 | } 19 | -------------------------------------------------------------------------------- /z.Foundation/fm_read.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | let fm = FileManager.default 4 | 5 | let filePath = "/Users/wannabewize/Documents/str.txt" 6 | 7 | if fm.fileExists(atPath: filePath) { 8 | // 파일 핸들러 생성 9 | if let handler = FileHandle(forReadingAtPath: filePath) { 10 | handler.seek(toFileOffset: 3) 11 | let data = handler.readData(ofLength: 6) 12 | // 읽어온 데이터를 문자열로 변환 13 | if let str = String(data: data, encoding: .utf8) { 14 | print("파일 읽기 : \(str)") 15 | } 16 | } 17 | } 18 | 19 | // 파일 쓰기용 파일 핸들러 20 | if let handler2 = FileHandle(forUpdatingAtPath: filePath) { 21 | // 파일에 데이터 쓰기 22 | let data2 = "새 데이타".data(using: .utf8) 23 | if let dataForWrite = data2 { 24 | // 파일 마지막에 덧붙이기 25 | handler2.seekToEndOfFile() 26 | handler2.write(dataForWrite) 27 | // 파일 저장 및 닫기 28 | handler2.synchronizeFile() 29 | handler2.closeFile() 30 | } 31 | } 32 | else { 33 | print("파일 쓰기 불가능") 34 | } -------------------------------------------------------------------------------- /z.Foundation/json_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "device": [ 3 | { 4 | "name": "iPhone5s", 5 | "spec": { 6 | "screen": 4, 7 | "cpu": "a7" 8 | } 9 | }, 10 | { 11 | "name": "iPad Air", 12 | "spec": { 13 | "screen": 9.8, 14 | "cpu": "a7" 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /z.Foundation/json_parsing.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // 콘솔에서 동작시키는 경우, 경로 설정이 잘 된다. 4 | let url = URL(fileURLWithPath: "json_data.json") 5 | 6 | // 파일 존재 확인 7 | let fm = FileManager.default 8 | if !fm.fileExists(atPath: url.path) { 9 | print("JSON 파일 접근 안됨 : ", url.path) 10 | exit(1) // program exit 11 | } 12 | 13 | do { 14 | let data = try Data(contentsOf: url) 15 | let result = try JSONSerialization.jsonObject(with: data, options: []) 16 | 17 | if let root = result as? [String: Any], 18 | let devices = root["device"] as? [Any], 19 | let iPhone7 = devices[0] as? [String:Any] { 20 | 21 | print("iPhone7 : ", iPhone7) 22 | if let spec = iPhone7["spec"] as? [String:Any], 23 | let cpu = spec["cpu"] as? String { 24 | print("iPhone7's cpu is", cpu) 25 | } 26 | } 27 | } 28 | catch let error { 29 | print("Error : ", error.localizedDescription) 30 | } 31 | 32 | // 참고 : https://developer.apple.com/swift/blog/?id=37 -------------------------------------------------------------------------------- /z.Foundation/notification.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | // 알림 센터와 알림 이름 5 | let notiCenter = NotificationCenter.default 6 | let NotiName = NSNotification.Name("CustomNotification") 7 | 8 | // 알림 감시용 클래스 생성. NSObject 상속 필요 9 | class MyClass : NSObject { 10 | // 알림이 발생하면 동작하는 메소드 11 | func handleNoti(noti : Notification) { 12 | print("알림 발생! ", noti.userInfo) 13 | } 14 | } 15 | 16 | // 알림 센터에 알림에 대한 감시자 객체 등록 17 | let obj = MyClass() 18 | notiCenter.addObserver(obj, selector: #selector(MyClass.handleNoti(noti:)), name:NotiName, object: nil) 19 | 20 | // 알림 발송 21 | notiCenter.post(name: NotiName, object: nil) 22 | 23 | // 알림 발송(알림 객체로) 24 | let noti = Notification(name: NotiName, object: obj, userInfo: ["Info":"This is Example"]) 25 | notiCenter.post(noti) 26 | -------------------------------------------------------------------------------- /z.Foundation/nsobject_description.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 객체 설명 3 | */ 4 | 5 | import Foundation 6 | 7 | NSLog("Hello %@", "Foundation") 8 | NSLog("%d + %d = %d", 1, 2, (1+2)) 9 | 10 | class Rectangle : NSObject { 11 | var width = 0 12 | var height = 0 13 | 14 | override var description: String { 15 | return "사각형 가로 : \(width) - 세로 : \(height)" 16 | } 17 | } 18 | 19 | 20 | let obj = Rectangle() 21 | obj.width = 10 22 | obj.height = 20 23 | 24 | NSLog("%@", obj) 25 | print("\(obj)") 26 | -------------------------------------------------------------------------------- /z.Foundation/nsobject_equal.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | class Rectangle : NSObject { 4 | var width : Int 5 | var height : Int 6 | 7 | init(width : Int, height : Int) { 8 | self.width = width 9 | self.height = height 10 | } 11 | 12 | override func isEqual(_ object: Any?) -> Bool { 13 | // 옵셔널 타입의 파라미터, AnyObject 타입 비교 14 | if let other = object as? Rectangle { 15 | // 내용(가로와 세로 길이) 비교 16 | return self.width == other.width && self.height == other.height 17 | } 18 | return false 19 | } 20 | } 21 | 22 | 23 | // 24 | // Swift용 == 25 | // 26 | //extension Rectangle { 27 | // static func ==(lhs : Rectangle, rhs : Rectangle) -> Bool { 28 | // return lhs.width == rhs.width && lhs.height == rhs.height 29 | // } 30 | //} 31 | 32 | let obj1 = Rectangle(width: 10, height: 10) 33 | let obj2 = Rectangle(width: 10, height: 10) 34 | let obj3 = Rectangle(width: 10, height: 20) 35 | 36 | // isEqual을 구현하면 ==도 동작한다. 37 | print("obj.isEqual : ", obj1.isEqual(obj2)) 38 | print("obj == obj : ", obj1 == obj3) 39 | 40 | 41 | let obj = obj1 42 | print("obj === obj1 : ", obj === obj1) -------------------------------------------------------------------------------- /z.Foundation/nsobject_typecheck.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * NSObject와 타입 검사 3 | */ 4 | 5 | import Foundation 6 | 7 | class Shape : NSObject { 8 | } 9 | 10 | class Rectangle : Shape { 11 | } 12 | 13 | let child = Rectangle() 14 | 15 | 16 | 17 | if child.isMember(of: Shape.self) { 18 | print("child는 Shape 클래스") 19 | } 20 | 21 | if child.isKind(of: Shape.self) { 22 | print("child는 Shape의 자식 클래스") 23 | } 24 | 25 | // Swift의 is로 타입 검사 26 | if child is Shape { 27 | print("child is Shape 클래스") 28 | } 29 | -------------------------------------------------------------------------------- /z.Foundation/protocol_optional.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 프로토콜 내 선택 구현 3 | */ 4 | import Foundation 5 | 6 | @objc protocol Baking { 7 | func baking() // 필수 구현 메소드 8 | @objc optional func makeDough() // 선택 구현 메소드 9 | @objc optional var since : Int { get } 10 | } 11 | 12 | class BigBakery : Baking { 13 | func baking() { 14 | print("빵 굽기") 15 | } 16 | 17 | // 선택 메소드 18 | func makeDough() { 19 | print("반죽하기") 20 | } 21 | 22 | // 선택 프로퍼티 23 | var since: Int = 2006 24 | } 25 | 26 | print("== Big Bakery") 27 | let bakery1 = BigBakery() 28 | bakery1.baking() 29 | bakery1.makeDough() 30 | print(bakery1.since) 31 | 32 | 33 | print("== Small Bakery") 34 | // 필수 항목만 구현한 클래스 35 | class SmallBakery : Baking { 36 | func baking() { 37 | print("빵 굽기") 38 | } 39 | } 40 | 41 | 42 | let bakery2 = SmallBakery() 43 | bakery2.baking() 44 | // 미구현으로 인한 컴파일 에러 45 | //bakery2.makeDough() 46 | 47 | 48 | // 49 | // 프로토콜 타입으로 사용 50 | // 51 | let bakery3 : Baking = BigBakery() 52 | let bakery4 : Baking = SmallBakery() 53 | 54 | bakery3.baking() 55 | 56 | // 구현 여부 불투명! 57 | //bakery3.makeDough() 58 | //bakery4.makeDough() 59 | 60 | // 타입 정보 알아보기 61 | print( type(of: bakery3.makeDough )) // Optional<(()) -> ()> 62 | print( type(of: bakery3.since )) // Optional 63 | 64 | bakery3.makeDough!() 65 | bakery4.makeDough?() 66 | // bakery4.makeDough!() -------------------------------------------------------------------------------- /z.Foundation/selector.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 셀렉터 3 | */ 4 | 5 | import Foundation 6 | 7 | class MyClass : NSObject { 8 | func greeting() { 9 | print("Hello") 10 | } 11 | 12 | func justDoIt() { 13 | let sel = #selector(greeting) 14 | print(sel) 15 | } 16 | } 17 | 18 | 19 | // Selector - outside 20 | let sel1 = #selector(MyClass.greeting) 21 | print(sel1) 22 | 23 | let obj = MyClass() 24 | print("셀렉터 반응 여부 : ", obj.responds(to: sel1)) 25 | 26 | // Selector - declared in Inside 27 | obj.justDoIt() 28 | 29 | 30 | // @objc를 이용한 ObjC 런타임 31 | class MyClass2 { 32 | @objc func greeting() { 33 | print("Hello") 34 | } 35 | } 36 | 37 | let obj2 = MyClass2() 38 | // 클래스 이름 대신 객체 참조 사용 가능 39 | let sel2 = #selector(obj2.greeting) 40 | 41 | extension MyClass { 42 | func greeting(person : String) { 43 | print("How are you? \(person)") 44 | } 45 | 46 | func greeting(who person : String) { 47 | print("How are you? \(person)") 48 | } 49 | 50 | func greeting(_ person : String){} 51 | 52 | func greeting(person : String, emotion : String) { 53 | } 54 | 55 | func greeting(person : String, with emotion : String) { 56 | } 57 | 58 | // 첫 번째 파라미터에 외부 파라미터 이름 설정 59 | func greeting(who person : String, emotion : String) { 60 | } 61 | 62 | // 두 번째 파라미터에 외부 파라미터 이름 생략 63 | func greeting(person : String, _ emotion : String) { 64 | } 65 | } 66 | 67 | let sel3 = #selector(MyClass.greeting(person:)) 68 | let sel4 = #selector(MyClass.greeting(who:)) 69 | let sel5 = #selector(MyClass.greeting(_:)) 70 | 71 | print(sel3) 72 | print(sel4) 73 | print(sel5) 74 | 75 | 76 | let sel6 = #selector(MyClass.greeting(person:emotion:)) 77 | let sel7 = #selector(MyClass.greeting(person:with:)) 78 | let sel8 = #selector(MyClass.greeting(who:emotion:)) 79 | let sel9 = #selector(MyClass.greeting(person:_:)) 80 | 81 | print(sel6) 82 | print(sel7) 83 | print(sel8) -------------------------------------------------------------------------------- /z.Foundation/selector_ambiguous.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * selector ambiguous 3 | */ 4 | 5 | import Foundation 6 | 7 | class MyClass : NSObject { 8 | func greeting() {} 9 | 10 | func greeting(who : String) {} 11 | } 12 | 13 | // ambiguous Error 14 | //let sel = #selector(MyClass.greeting) 15 | 16 | // reference error 17 | //let sel2 = #selector(MyClass.greeting as () -> () ) 18 | 19 | // ambiguous error를 피하기 위한 방법 20 | let obj = MyClass() 21 | let sel3 = #selector(obj.greeting as ()->()) 22 | print(sel3) 23 | 24 | let sel4 = #selector(MyClass.greeting(who:)) 25 | print(sel4) -------------------------------------------------------------------------------- /z.Foundation/selector_perform.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 셀렉터 동작 체크, 실행 3 | */ 4 | 5 | import Foundation 6 | 7 | class SayClass : NSObject { 8 | func sayYes() { 9 | print("YES!") 10 | } 11 | 12 | func say(what : String) { 13 | print("\(what)!") 14 | } 15 | } 16 | 17 | let say = SayClass() 18 | 19 | // 셀렉터 검사 20 | let sel = #selector(SayClass.sayYes) 21 | if say.responds(to: sel) { 22 | print("셀렉터 동작 확인") 23 | say.perform(sel) 24 | } 25 | else { 26 | print("셀렉터 동작 안함") 27 | } 28 | 29 | // 파라미터가 있는 셀렉터 실행 30 | say.perform(#selector(SayClass.say(what:)), with: "Good Morning") 31 | 32 | -------------------------------------------------------------------------------- /z.Foundation/selector_staticMethod.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 타입 메소드에 대한 셀렉터 3 | */ 4 | 5 | import Foundation 6 | 7 | class MyClass : NSObject { 8 | 9 | 10 | static func goodbye() {} 11 | 12 | static func goodnight() {} 13 | 14 | static func goodnight(who : String) {} 15 | } 16 | 17 | let sel1 = #selector(MyClass.goodbye) 18 | print(sel1) 19 | 20 | let sel2 = #selector(MyClass.goodnight as () -> () ) 21 | print(sel2) 22 | 23 | let sel3 = #selector(MyClass.goodnight(who:)) 24 | print(sel3) -------------------------------------------------------------------------------- /z.Foundation/string1.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // 4 | // 문자열 선언 5 | // 6 | 7 | var nsStr : NSString = "Hello, Foundation" 8 | // Swift의 String 타입의 문자열 9 | var swiftStr = "Hello, Swift" 10 | 11 | // 12 | // 문자열 변환 13 | // 14 | 15 | // NSString을 String으로 – as 필요 16 | var str1 : String = nsStr as String 17 | 18 | // Swift String에서 NSString으로 타입 변환 19 | var str2 : NSString = swiftStr as NSString 20 | 21 | 22 | // 23 | // 문자열 포맷 24 | // 25 | var formattedStr1 = NSString(format: "%d + %d = %d", 1, 2, (1+2)) 26 | var formattedStr2 = NSString(format: "%@ %@", "Hello", "Foundation") 27 | 28 | // 29 | // 문자열 비교 : equality 30 | // 31 | 32 | 33 | let nsStr1 : NSString = "Hello Foundation" 34 | let nsStr2 : NSString = "Hello Foundation" 35 | 36 | let swiftStr2 = "Hello Foundation" 37 | 38 | print("NSString == ", nsStr1 == nsStr2) 39 | print("NSString === ", nsStr1 === nsStr2) 40 | print("NSString.isEqual(to:) : ", nsStr1.isEqual(to: swiftStr2)) 41 | // Swift String에서 isEqual(to:) 사용 불가 42 | swiftStr2.isEqual(nsStr1) 43 | 44 | // 45 | // 문자열 비교 : compare 46 | // 47 | 48 | let numStr1 : NSString = "1" 49 | let numStr2 = "09" 50 | 51 | // Descending : “1” > “09” 52 | let ret1 = numStr1.compare(numStr2) 53 | print("1 compare 09 : isDescending", ret1 == ComparisonResult.orderedDescending) 54 | 55 | // Ascending : 1 < 09 56 | let ret2 = numStr1.compare(numStr2, options: .numeric) 57 | print("1 compare(numeric) 09 : isAscending", ret2 == ComparisonResult.orderedAscending) 58 | 59 | 60 | let ret3 = "HELLO".compare("hello", options: .caseInsensitive) 61 | 62 | print("HELLO compare(caseInsensitive) hello, isSame: ", ret3 == ComparisonResult.orderedSame) 63 | 64 | 65 | // 66 | // 문자열 길이 67 | // 68 | 69 | print("NSString.length : ", nsStr.length) 70 | print("Swift String.characters.count : ", swiftStr.characters.count) 71 | -------------------------------------------------------------------------------- /z.Foundation/string2.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | let nsStr : NSString = "Hello Foundation" 5 | 6 | let range : NSRange = nsStr.range(of: "ell") 7 | print("location : ", range.location) // 1 8 | print("length : ", range.length) // 3 9 | 10 | if range.location != NSNotFound { 11 | print("문자열 검색 \(range)") 12 | } 13 | else { 14 | print("못찾음") 15 | } 16 | 17 | // 옵션을 이용해서 대소문자 구별 없이 찾기 18 | let range2 = nsStr.range(of: "fo", options: .caseInsensitive) 19 | print("rangeOfString.CaseInsensitiveSearch : ",range2) 20 | 21 | 22 | let swiftStr = "Hello Swift" 23 | 24 | let range3 : Range? = swiftStr.range(of: "sw") 25 | print("range3 : ", range3) // nil 26 | let range4 = swiftStr.range(of:"sw", options: .caseInsensitive) 27 | //range4 // 6..<8 28 | print("Swift String. rangeOfString : ", range4) 29 | 30 | // 31 | // Substring 32 | // 33 | 34 | let subStr1 = nsStr.substring(from:3) 35 | 36 | // 시작 인덱스. String.Index 타입. 0에서 3뒤로. 37 | let index = swiftStr.index(swiftStr.startIndex, offsetBy: 3) 38 | let subStr2 = swiftStr.substring(from:index) 39 | 40 | // String.Index의 범위 41 | let range5 : Range = swiftStr.startIndex ..< swiftStr.index(swiftStr.startIndex, offsetBy: 5) 42 | let subStr3 = swiftStr.substring(with: range5) // "Hello" 43 | 44 | 45 | // Appending 46 | 47 | let nsStr2 : NSString = " Hello Foundation " 48 | 49 | // 공백 문자 제거 50 | let trimStr = nsStr2.trimmingCharacters(in: CharacterSet.whitespaces) 51 | let appendStr = trimStr.appending("!") 52 | 53 | let swiftStr2 = " Hello Swift " 54 | print(swiftStr2) 55 | let trimStr2 = swiftStr2.trimmingCharacters(in: CharacterSet.whitespaces) 56 | print(trimStr2) 57 | let appendStr2 = trimStr2.appending("!") 58 | print(appendStr2) 59 | 60 | 61 | // 62 | // 타입 변환 63 | // 64 | 65 | let numStr : NSString = "123" 66 | print(numStr.integerValue) // 123 67 | 68 | let numStr2 : NSString = "3.14" 69 | print(numStr2.floatValue) 70 | 71 | let boolStr : NSString = "1" 72 | print(boolStr.boolValue) // true 73 | 74 | 75 | 76 | // 77 | // 대소문자 변환 78 | // 79 | 80 | // NSString 81 | let lowerStr : NSString = "abcd" 82 | let upperStr = lowerStr.uppercased 83 | 84 | // Swift String 85 | let upperStr2 = "hello".uppercased() 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /z.Foundation/string_file.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | var nsStr : NSString = "Hello Swift" 4 | 5 | // 파일 경로 6 | let docPath : NSString = "/Users/wannabewize/Documents" 7 | // 경로 문자열을 다루는 API 8 | let filePath = docPath.appendingPathComponent("str.txt") 9 | 10 | do { 11 | try nsStr.write(toFile: filePath, atomically: true, encoding: String.Encoding.utf8.rawValue) 12 | print("파일 저장 성공") 13 | } 14 | catch let error { 15 | print("파일 저장 실패 : \(error)") 16 | } 17 | 18 | // 파일에서 문자열 읽기 19 | do { 20 | let nsStr2 = try NSString(contentsOfFile: filePath, encoding: String.Encoding.utf8.rawValue) 21 | print("파일 읽기 : \(nsStr2)") 22 | } 23 | catch let error { 24 | print("파일 읽기 실패 : \(error)") 25 | } 26 | 27 | 28 | // 29 | // Swift String의 파일 읽기/쓰기 30 | // 31 | 32 | let filePath2 = docPath.appendingPathComponent("str2.txt") 33 | let swiftStr = "Hello Swift" 34 | do { 35 | try swiftStr.write(toFile: filePath2, atomically: true, encoding: .utf8) 36 | print("파일 저장 성공") 37 | } 38 | catch let error { 39 | print("파일 저장 실패 : \(error)") 40 | } 41 | 42 | // 파일에서 문자열 읽기 43 | let swiftStr2 = try? String(contentsOfFile: filePath2) 44 | print(swiftStr2) -------------------------------------------------------------------------------- /z.Foundation/string_mutable.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | var mStr : NSMutableString = NSMutableString(string: "가나다") 5 | mStr.append("라") // 가나다라 6 | mStr.deleteCharacters(in: NSMakeRange(0, 2)) // 다라 7 | mStr.insert("가져", at: 1) // 다가져라 8 | -------------------------------------------------------------------------------- /z.Foundation/string_referenceType.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | var mStr1 = NSMutableString(string: "Hello") 4 | var mStr2 = mStr1 5 | 6 | mStr1.append(" Foundation") 7 | 8 | print(mStr1) // Hello Foundation 9 | print(mStr2) // Hello Foundation 10 | 11 | 12 | var str1 = "Hello Swift" 13 | var str2 = str1 14 | 15 | let ch : Character = "!" 16 | str1.append(ch) 17 | 18 | print(str1) // Hello Swift! 19 | print(str2) // Hello Swift 20 | 21 | -------------------------------------------------------------------------------- /z.Foundation/thread1.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | // 쓰레드 클래스 6 | class MyThread : Thread { 7 | var title : String 8 | init(_ title : String) { self.title = title } 9 | 10 | // 멀티 쓰레드로 동작하는 코드 11 | override func main() { 12 | for i in 0...10 { 13 | // NSLog는 Thread Safe 함수 14 | print("\(title) count \(i)") 15 | } 16 | } 17 | } 18 | 19 | // 쓰레드 객체 생성 20 | let thread1 = MyThread("Thread1") 21 | thread1.start() 22 | 23 | let thread2 = MyThread("Thread2") 24 | thread2.start() 25 | 26 | // 애플리케이션 종료 막기 27 | while !( thread1.isFinished && thread2.isFinished ) { 28 | Thread.sleep(forTimeInterval: 1) 29 | } 30 | -------------------------------------------------------------------------------- /z.Foundation/thread2.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // 쓰레드 클래스 4 | class MyOperation : Operation { 5 | var title : String 6 | init(_ title : String) { self.title = title } 7 | 8 | // 멀티 쓰레드로 동작하는 코드 9 | override func main() { 10 | for i in 0...10 { 11 | // NSLog는 thread Safe 12 | NSLog("\(title) count \(i)") 13 | } 14 | } 15 | } 16 | 17 | 18 | // 큐 생성, 동시에 동작하는 쓰레드 개수 설정 19 | let queue = OperationQueue() 20 | queue.maxConcurrentOperationCount = 2 21 | 22 | // 오퍼레이션 객체 생성, 큐에 추가 23 | var operation1 = MyOperation("Operation1") 24 | queue.addOperation(operation1) 25 | 26 | var operation2 = MyOperation("Operation2") 27 | queue.addOperation(operation2) 28 | 29 | var operation3 = MyOperation("Operation3") 30 | queue.addOperation(operation3) 31 | 32 | queue.addOperation { 33 | for i in 0...10 { 34 | NSLog("클로저 기반의 쓰레드 \(i)") 35 | } 36 | } 37 | 38 | queue.waitUntilAllOperationsAreFinished() 39 | -------------------------------------------------------------------------------- /z.Foundation/timer.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | class Alarm : NSObject { 5 | func ring(timer : Timer) { 6 | print("Wake UP!") 7 | } 8 | } 9 | 10 | let obj = Alarm() 11 | var timer = Timer.scheduledTimer(timeInterval: 0.5, target: obj, selector: #selector(Alarm.ring(timer:)), userInfo: nil, repeats: true) 12 | 13 | // 커맨드 라인툴의 환경상 바로 동작 14 | timer.fire() 15 | 16 | // macOS 10.12 17 | //Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { timer in 18 | // print("클로저를 이용한 타이머") 19 | //} 20 | -------------------------------------------------------------------------------- /z.Foundation/type_convert.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 파운데이션 데이터 타입과 Swift 타입 간 변환 3 | */ 4 | import Foundation 5 | 6 | // NSString을 String으로 7 | let nsStr : NSString = "ABC" 8 | let str : String = nsStr as String 9 | print(str) 10 | let nsStr2 : NSString = str as NSString 11 | print(nsStr2) 12 | 13 | 14 | // NSArray <-> Array 15 | let nsArray = NSArray(arrayLiteral: "a", "b", "c") 16 | let array = nsArray as! Array 17 | print(array) 18 | let nsArray2 = array as NSArray 19 | print(nsArray2) 20 | 21 | // NSDictionary <-> Dictionary 22 | let nsDic = NSDictionary(dictionaryLiteral: (1, "one"), (2, "two"), (3, "three")) 23 | print(nsDic) 24 | let dic = nsDic as! Dictionary 25 | print(dic) 26 | let nsDic2 = dic as NSDictionary 27 | print(nsDic2) -------------------------------------------------------------------------------- /z.Foundation/url.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | let urlStr = "https://www.google.com/search?q=아이폰" 4 | 5 | 6 | // 7 | // URL 퍼센트 인코딩/디코딩 8 | // 9 | let encoded = urlStr.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) 10 | print(encoded) 11 | let decoded = encoded?.removingPercentEncoding 12 | print(decoded) 13 | 14 | 15 | // URL 구성 요소 16 | if let encoded = urlStr.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) { 17 | if let url = URL(string: encoded) { 18 | print("scheme : \(url.scheme)") 19 | print("host : \(url.host)") 20 | print("path : \(url.path)") 21 | print("query : \(url.query)") 22 | } 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /z.Foundation/url_resource_loading.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | let url = URL(string: "http://google.com")! 4 | let str = try? String(contentsOf: url) 5 | 6 | print(str) 7 | 8 | 9 | let url2 = URL(string: "http://www.ibiblio.org/wm/paint/auth/munch/munch.scream.jpg")! 10 | let data = try? Data(contentsOf: url2) 11 | 12 | print(data?.count) -------------------------------------------------------------------------------- /z.Generics/custom_type_generics.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 제네릭스를 사용하는 함수와 타입 작성 3 | */ 4 | 5 | 6 | // 제네릭스로 타입 추상화 함수 7 | 8 | func printValue(_ v : T) { 9 | print("Value \(v)") 10 | } 11 | 12 | printValue("a") 13 | printValue(1) 14 | printValue(1.3) 15 | 16 | 17 | 18 | // 제네릭스를 사용하는 클래스 19 | class Hospital { 20 | func hospitalize(_ patient : T) { 21 | print("병원에 입원") 22 | } 23 | } 24 | 25 | class Human {} 26 | 27 | struct Pet {} 28 | 29 | 30 | // Human 타입 객체 다루기 31 | let hospital = Hospital() 32 | 33 | let patient = Human() 34 | hospital.hospitalize(patient) 35 | 36 | 37 | // Pet 타입 객체를 다루기 38 | let petHospital = Hospital() 39 | 40 | let kitty = Pet() 41 | petHospital.hospitalize(kitty) 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /z.Generics/generics.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 제네릭스를 사용하는 배열과 딕셔너리 3 | */ 4 | 5 | var array1 = Array() 6 | 7 | array1.append(1) 8 | print(array1) 9 | 10 | array1.remove(at: 0) 11 | print(array1) 12 | 13 | 14 | var array2 = Array() 15 | 16 | array2.append("a") 17 | array2.append("b") 18 | 19 | 20 | var dictionary = Dictionary() 21 | 22 | dictionary.updateValue(1, forKey: "ONE") 23 | print(dictionary) 24 | dictionary.removeValue(forKey: "ONE") 25 | print(dictionary) -------------------------------------------------------------------------------- /z.Operator/custom_operator.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 커스텀 연산자 3 | */ 4 | 5 | struct Point { 6 | var x : Int 7 | var y : Int 8 | } 9 | 10 | 11 | // 새로운 연산자 정의 12 | 13 | infix operator ** 14 | 15 | extension Point { 16 | static func **(point : Point, times : Int) -> Point { 17 | return Point(x: point.x * times, y: point.y * times) 18 | } 19 | } 20 | 21 | let p1 = Point(x: 10, y: 10) 22 | let p2 = p1 ** 3 23 | print("Point(10,10) ** 3 : ", p2) 24 | 25 | 26 | // 27 | // 기존 연산자와 함께 사용하기 28 | // SE0077 29 | // https://github.com/apple/swift-evolution/blob/master/proposals/0077-operator-precedence.md 30 | // 31 | 32 | // 곱셈과 덧셈 중간 우선도, 왼쪽 결합 33 | precedencegroup customPrecedence { 34 | higherThan : AdditionPrecedence 35 | lowerThan : MultiplicationPrecedence 36 | associativity : left 37 | } 38 | 39 | infix operator *** : customPrecedence 40 | 41 | extension Point { 42 | static func +(left : Point, right : Point) -> Point { 43 | return Point(x: left.x + right.x, y: left.y + right.y) 44 | } 45 | 46 | static func ***(point : Point, times : Int) -> Point { 47 | return Point(x: point.x * times, y: point.y * times) 48 | } 49 | } 50 | 51 | 52 | let p3 = Point(x: 10, y: 10) 53 | let p4 = Point(x: 20, y: 20) 54 | 55 | 56 | // +, *** 연산자 함께 사용하기. *** 연산자가 + 보다 먼저 동작 57 | let p5 = p3 + p4 *** 2 58 | print("Point(10,10) + Point(20, 20) *** 2 : ", p5) 59 | -------------------------------------------------------------------------------- /z.Operator/equal.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 객체 비교 3 | */ 4 | 5 | struct Size { 6 | var width, height : Int 7 | } 8 | 9 | extension Size : Equatable { 10 | // == 연산자 기능 정의 11 | static func ==(lhs: Size, rhs: Size) -> Bool { 12 | return lhs.width == rhs.width && lhs.height == rhs.height 13 | } 14 | } 15 | 16 | var obj1 = Size(width: 10, height: 10) 17 | var obj2 = Size(width: 10, height: 10) 18 | var obj3 = Size(width: 20, height: 20) 19 | 20 | print("Size(10,10) == Size(10,10) : ", obj1 == obj2) // true 21 | print("Size(10,10) == Size(20,20) : ", obj1 == obj3) // false 22 | 23 | 24 | 25 | extension Size : Comparable { 26 | func size() -> Int { 27 | return width * height 28 | } 29 | 30 | static func <=(lhs: Size, rhs: Size) -> Bool { 31 | return lhs.size() <= rhs.size() 32 | } 33 | 34 | static func >=(lhs: Size, rhs: Size) -> Bool { 35 | return lhs.size() >= rhs.size() 36 | } 37 | 38 | static func >(lhs: Size, rhs: Size) -> Bool { 39 | return lhs.size() > rhs.size() 40 | } 41 | 42 | static func <(lhs: Size, rhs: Size) -> Bool { 43 | return lhs.size() < rhs.size() 44 | } 45 | } 46 | 47 | print("Size(10,10) <= Size(10,10) : ", obj1 <= obj2) // true 48 | print("Size(10,10) < Size(20,20) : ", obj1 < obj3) // true 49 | print("Size(10,10) > Size(20, 20) : ", obj2 > obj3) 50 | -------------------------------------------------------------------------------- /z.Operator/overloading.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 연산자 재정의 3 | */ 4 | 5 | struct Point { 6 | var x : Int 7 | var y : Int 8 | 9 | static func +(left : Point, right : Point) -> Point { 10 | // 새로운 객체 반환 11 | return Point(x: left.x + right.x, y: left.y + right.y) 12 | } 13 | } 14 | 15 | // Swift2 방식. Swift3에서도 사용 가능 16 | /* 17 | func +(left : Point, right : Point) -> Point { 18 | return Point(x: left.x + right.x, y: left.y + right.y) 19 | } 20 | */ 21 | 22 | var p1 = Point(x: 10, y: 10) 23 | var p2 = Point(x: 20, y: 20) 24 | 25 | print("Point + Point : ", p1 + p2) // (30, 30) 26 | 27 | 28 | extension Point { 29 | static // 단항 연산자. 후위 연산자. 30 | postfix func ++(point : inout Point) -> Point { 31 | point.x += 1 32 | point.y += 1 33 | return point 34 | } 35 | } 36 | 37 | 38 | var p3 = Point(x: 10, y: 10) 39 | print("Point++ : ", p3++) // (11,11) 40 | 41 | extension Point { 42 | static prefix func -(point : Point) -> Point { 43 | var another = point 44 | another.x = -point.x 45 | another.y = -point.y 46 | return another 47 | } 48 | } 49 | 50 | print("-Point : ", -p1) -------------------------------------------------------------------------------- /z.Operator/subscript.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 첨자 표기(Subscript) 3 | */ 4 | 5 | class MyClass { 6 | // 숫자 인덱스를 문자로 7 | subscript (index : Int) -> String { 8 | return String(index) 9 | } 10 | 11 | // 문자 인덱스는 문자열의 길이 12 | subscript ( str : String ) -> Int { 13 | return str.characters.count 14 | } 15 | } 16 | 17 | var obj = MyClass() 18 | print("커스텀 타입에 첨자 표기[3] : ", obj[3]) // "3" 19 | print("커스텀 타입에 첨자 표기[\"77\"] : ", obj["77"]) // 2 20 | 21 | // 22 | // 기존 타입(String)의 extension 23 | // 24 | 25 | extension String { 26 | // 범위 내 문자열. 27 | subscript(range:CountableRange) -> String? { 28 | guard let start = self.index(startIndex, offsetBy: range.startIndex, limitedBy : endIndex), 29 | let end = self.index(startIndex, offsetBy: range.endIndex, limitedBy: endIndex) else { 30 | return nil 31 | } 32 | return self[start.. String? { 37 | return self[index.. Double 8 | } 9 | 10 | 11 | class Rectangle : SizeMeasurable { 12 | var width, height : Double 13 | init(width : Double, height : Double) { 14 | self.width = width 15 | self.height = height 16 | } 17 | func size() -> Double { 18 | return self.width * self.height 19 | } 20 | } 21 | 22 | class Circle : SizeMeasurable { 23 | var r : Double 24 | init(r : Double) { 25 | self.r = r 26 | } 27 | 28 | func size() -> Double { 29 | return r * r * M_PI 30 | } 31 | } 32 | 33 | class Triangle : SizeMeasurable { 34 | var a , b, c : Double 35 | 36 | init(a : Double, b : Double, c : Double) { 37 | self.a = a 38 | self.b = b 39 | self.c = c 40 | } 41 | 42 | func size() -> Double { 43 | // 세 변의 길이로 삼각형 넓이 구하기 - 헤론 공식 44 | let s : Double = ( a + b + c ) / 2 45 | let result = sqrt( s * (s - a) * (s - b) * (s - c) ) 46 | return result 47 | } 48 | } 49 | 50 | var r = Rectangle(width: 10, height: 10) 51 | print(r.size()) 52 | 53 | var c = Circle(r: 10) 54 | print(c.size()) 55 | 56 | var t = Triangle(a: 3, b: 4, c: 5) 57 | print(t.size()) 58 | -------------------------------------------------------------------------------- /z.Protocol/initializer.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 프로토콜 내 Initializer 3 | */ 4 | 5 | // Initializer 6 | protocol Named { 7 | // Initializer 8 | init(name : String) 9 | 10 | // Failable Initializer 11 | init?() 12 | } 13 | 14 | class Monster : Named { 15 | let name : String 16 | // required로 작성 17 | required init(name: String) { 18 | self.name = name 19 | } 20 | 21 | // Failable Initializer는 non-Failable Initializer로 구현 가능 22 | required init() { 23 | self.name = "무명" 24 | } 25 | } 26 | 27 | var obj1 = Monster() 28 | print(obj1) 29 | 30 | 31 | var obj2 = Monster(name : "네임드") 32 | print(obj2) -------------------------------------------------------------------------------- /z.Protocol/property.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 프로토콜과 프로퍼티 3 | */ 4 | 5 | // 프로퍼티의 get/set 설정 6 | protocol HoldingBreath { 7 | var duration : Int { get set } 8 | } 9 | 10 | // 저장 프로퍼티로 구현 11 | class Dolphin : HoldingBreath { 12 | var duration : Int = 9999 13 | 14 | } 15 | 16 | // 계산 프로퍼티로 구현 17 | class Human : HoldingBreath { 18 | var duration : Int { 19 | get { 20 | return 60 21 | } 22 | set {} 23 | } 24 | } 25 | 26 | let dolphin = Dolphin() 27 | print(dolphin.duration) 28 | 29 | let diver = Human() 30 | print(diver.duration) 31 | -------------------------------------------------------------------------------- /z.Protocol/protocol_basic.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 프로토콜 3 | */ 4 | 5 | // 프로토콜 선언 6 | protocol Singing { 7 | func sing() 8 | } 9 | 10 | // 클래스 채택 11 | class Bird : Singing { 12 | func sing() { 13 | print("짹짹짹~") 14 | } 15 | } 16 | 17 | // 구조체 채택 18 | struct Cat : Singing { 19 | func sing() { 20 | print("갸르릉 갸르릉") 21 | } 22 | } 23 | 24 | let sparrow = Bird() 25 | sparrow.sing() 26 | 27 | let kitty = Cat() 28 | kitty.sing() 29 | 30 | 31 | protocol Dancing { 32 | func dance() 33 | } 34 | 35 | // 다수의 프로토콜 채택 36 | class Human : Dancing, Singing { 37 | func sing() { 38 | print("랄라라~") 39 | } 40 | 41 | func dance() { 42 | print("춤추기") 43 | } 44 | } 45 | 46 | let iu = Human() 47 | iu.sing() 48 | iu.dance() -------------------------------------------------------------------------------- /z.Protocol/protocol_extensioin.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 프로토콜 extension 3 | */ 4 | 5 | protocol Movable { 6 | } 7 | 8 | struct Human : Movable { 9 | } 10 | 11 | // 프로토콜 확장 – 구현 작성 가능 12 | extension Movable { 13 | func move() { 14 | print("Go! go! go!") 15 | } 16 | } 17 | 18 | var man = Human() 19 | man.move() // 기본 구현처럼 동작 20 | 21 | 22 | protocol Flyable { 23 | } 24 | 25 | extension Flyable { 26 | func fly() { 27 | print("Fly me to the moon") 28 | } 29 | } 30 | 31 | class Superman : Movable, Flyable { 32 | // 프로토콜 구현을 재정의 33 | func move() { 34 | print("Move Fast") 35 | } 36 | } 37 | 38 | var superman = Superman() 39 | superman.move() 40 | superman.fly() 41 | 42 | -------------------------------------------------------------------------------- /z.Protocol/protocol_type.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 프로토콜 - 타입으로 사용 3 | */ 4 | 5 | protocol Singing { 6 | func sing() 7 | } 8 | 9 | class Human : Singing { 10 | func sing() { 11 | print("Sing Sing Sing") 12 | } 13 | 14 | func drink() { 15 | print("Drink") 16 | } 17 | } 18 | 19 | // 클래스 타입으로 선언한 객체 20 | var obj1 : Human = Human() 21 | // 프로토콜에 선언한 메소드 사용 22 | obj1.sing() 23 | // 프로토콜에 선언하지는 않았지만 클래스에 작성한 메소드 24 | obj1.drink() 25 | 26 | // 프로토콜 타입으로 선언한 변수 27 | var obj2 : Singing = Human() 28 | // 프로토콜에 선언한 메소드 사용 29 | obj2.sing() 30 | // 프로토콜에 선언하지는 않았지만 클래스에 작성한 메소드 - 에러 31 | //obj2.drink() 32 | 33 | 34 | // 파라미터 타입으로 선언 35 | func sayHello(who : String, and : Singing) { 36 | print("Hello. 파라미터 타입은 Singing 프로토콜") 37 | } 38 | sayHello(who: "IU", and : obj2) 39 | 40 | protocol Dancing { 41 | func dance() 42 | } 43 | 44 | // 변수 선언 45 | class Idol : Singing, Dancing { 46 | func sing() { 47 | print("Sing Sing Sing") 48 | } 49 | 50 | func dance() { 51 | print("Dance Dance") 52 | } 53 | } 54 | 55 | // 두 개 이상의 프로토콜 ( protocol composition ) 56 | func entertain(who : Singing & Dancing) { 57 | print("Singing, Dancing 프로토콜 타입") 58 | } 59 | 60 | var exid = Idol() 61 | entertain(who : exid) -------------------------------------------------------------------------------- /z.Protocol/static_method.swift: -------------------------------------------------------------------------------- 1 | protocol Species { 2 | // 타입 메소드 3 | static func species() -> String 4 | // 타입 프로퍼티 선언 5 | static var averageLife : Int { get } 6 | } 7 | 8 | class Cow : Species { 9 | // 타입 프로퍼티 구현 10 | static var averageLife : Int { 11 | return 10 12 | } 13 | 14 | // 타입 메소드 구현 15 | static func species() -> String { 16 | return "소" 17 | } 18 | } 19 | 20 | print(Cow.averageLife) 21 | print(Cow.species()) -------------------------------------------------------------------------------- /z.TypeCheck/any.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Any 타입. 정수형과 문자열 값 대입 3 | // 4 | 5 | var anyVar : Any = 3 6 | print(anyVar, type(of:anyVar)) 7 | 8 | 9 | anyVar = "3" 10 | print(anyVar, type(of:anyVar)) 11 | 12 | //anyVar = nil // Error. 13 | 14 | struct MyStruct { 15 | var value = 1000 16 | } 17 | 18 | class MyClass { 19 | var value = 2000 20 | } 21 | 22 | // 구조체 객체 대입 23 | anyVar = MyStruct() 24 | print(anyVar, type(of:anyVar)) 25 | 26 | 27 | // 클래스 객체 대입 28 | anyVar = MyClass() 29 | print(anyVar, type(of:anyVar)) 30 | 31 | 32 | // 33 | // AnyObject 타입 34 | // 35 | 36 | var anyObj : AnyObject 37 | 38 | // Value 타입 대입은 불가. 39 | //anyObj = 10 // Error 40 | //anyObj = "Hello" // Error 41 | 42 | // 구조체도 밸류 타입으로 대입 불가 43 | //anyObj = MyStruct() 44 | 45 | // ReferenceType 인 클래스 객체는 가능 46 | anyObj = MyClass() 47 | print(anyObj, type(of:anyObj)) 48 | 49 | -------------------------------------------------------------------------------- /z.TypeCheck/type_alias.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * 타일 알리아스 3 | */ 4 | 5 | // 정수형 타입을 Century 타입으로 타입 알리아스 6 | typealias Century = Int 7 | 8 | var thisEra : Century 9 | thisEra = 21 10 | 11 | 12 | // 클로저 타입 알리아스 13 | typealias ResultHandler = (Int) -> Void 14 | 15 | func add(_ i : Int, _ j : Int, _ resultHandler : ResultHandler ) { 16 | let sum = i + j 17 | resultHandler(sum) 18 | } 19 | 20 | add(1, 2) { 21 | ret in 22 | print(ret) 23 | } -------------------------------------------------------------------------------- /z.TypeCheck/type_cast.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 타입 변환 3 | // 4 | 5 | let anyVal : Any = 3 6 | 7 | let intVal1 = anyVal as? Int // 옵셔널 타입 8 | print(intVal1) 9 | 10 | let intVal2 = anyVal as! Int // Non-Optional Type 11 | print(intVal2) 12 | 13 | let strVal1 = anyVal as? String // 변환 실패. nil 14 | //let strVal2 = anyVal as! String // 변환 실패. 런타임 에러 15 | 16 | // 옵셔널 바인딩 17 | if let intVal3 = anyVal as? Int { 18 | print("변환 성공") 19 | } 20 | 21 | 22 | // 클래스 상속 23 | class Animal {} 24 | 25 | class Dog : Animal {} 26 | 27 | class Cat : Animal {} 28 | 29 | let raz = Cat() 30 | 31 | // Upcasting은 항상 성공. as 사용 가능 32 | let animal = raz as Animal 33 | 34 | 35 | // Dog 객체를 Animal 타입으로 36 | let obj : Animal = Dog() 37 | 38 | // Downcasting 100% 가능하지 않으므로 as 사용 불가 39 | //let doggy1 = obj as Dog // 컴파일 에러 40 | let doggy2 = obj as? Dog // 변환 성공. 옵셔널 타입 41 | let doggy3 = obj as! Dog // 변환 성공. Non-Optional Type 42 | 43 | let doggy4 = obj as? Cat // 변환 실패 - nil 44 | //let doggy5 = obj as! Cat // 변환 실패. 런타임 에러 45 | 46 | 47 | // 48 | // 프로토콜과 타입 변환 49 | // 50 | 51 | protocol Sing {} 52 | 53 | struct Bird : Sing {} 54 | 55 | let sparrow = Bird() 56 | 57 | let singing = sparrow as Sing -------------------------------------------------------------------------------- /z.TypeCheck/type_check.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * 타입 체크 3 | */ 4 | 5 | print("== Any 타입과 타입 체크") 6 | var anyVal : Any = 3 7 | 8 | if anyVal is Int { 9 | print("정수 타입") 10 | } 11 | 12 | 13 | // 14 | // 클래스 상속과 타입 체크 15 | // 16 | print("== 클래스 상속과 타입 체크") 17 | class Animal { 18 | var name : String! 19 | init(name : String) { self.name = name } 20 | } 21 | 22 | class Dog : Animal {} 23 | 24 | class Cat : Animal {} 25 | 26 | let raz = Cat(name: "라즈") 27 | print("Cat type : ", raz is Cat) // true 28 | print("Animal type : ", raz is Animal) // true 29 | print("Doc type : ", raz is Dog) // false 30 | 31 | 32 | // 33 | // 프로토콜과 타입 체크 34 | // 35 | print("== 프로토콜과 타입 체크") 36 | protocol Sing {} 37 | protocol Dive {} 38 | 39 | struct Bird : Sing {} 40 | 41 | let sparrow = Bird() 42 | 43 | print("프로토콜 Sing 채택 검사 : ",sparrow is Sing) // true 44 | print("프로토콜 Dive 채택 검사 : ",sparrow is Dive) // false 45 | 46 | 47 | // 48 | // 함수 타입 체크 49 | // 50 | print("== 함수 타입 체크") 51 | func sayHello() { 52 | } 53 | func say(what : String) { 54 | } 55 | 56 | print("sayHello is () -> Void :", sayHello is ()->Void) 57 | print("say(what:) is () -> Void :", say is ()->Void) --------------------------------------------------------------------------------