하... 이제 옵셔널이다

 

옵셔널

- 사실 옵셔널에는 내용이 굉장히 적다.

- B.U.T. 어느 문법이던 중요하겠지만 Swift에서도 굉장히 중요한 표현이다

- 안드로이드 개발을 진행할 때는, 옵셔널이라는 명칭보다는 nullable이라는 단어를 사용했다.

- 스위프트의 특징인 안전성을 담보로 사용할 수 있는 기능이다

- 옵셔널과 옵셔널이 아닌 값은 철저히 다른 타입으로 인식하기 때문에, 컴파일 시점에서 오류를 걸러낸다.

 

그렇다면 왜 옵셔널을 사용하는가?

  • 함수의 전달인자의 값이 잘못된 값일 때
  • 매개변수를 굳이 넘기지 않아도 될 때
  • 열거형을 불러올 때, case에 존재하지 않을 때

앞에서 enum에서 알아봤 듯이, 옵셔널은 열거형이다

 

옵셔널 추출

  • 옵셔널 바인딩
    • if 사용 - if블록 내에서만 사용 가능
    • guard 사용 - 블록외의 블록에서 사용 가능
  • 암시적 추출
    • ! 사용 - 위험한 방법
struct Person{
	var name: String?
}

var person: Person = Person(name: "tree")

//if 사용
if let name = person.name{
	print(name) // tree
}

//guard 사용
guard let name = person.name else { ... }

print(name) // tree

//암시적 추출 사용(1)
let name = person.name!
print(name) // tree

var person2 = Person()
let name2 = person2.name! // 런타임 에러 발생

 

정리하려고 맘 먹고 작성 중인데... 잘못 먹은 것 같다..

함수

  • 앞서 말했 듯, Swift에서의 함수는 일급 시민이다

함수 vs 메서드

  • 메서드 : 구조체, 클래스, 열거형 등 특정 타입에 연관되어 사용하는 함수
  • 함수 : 모듈 전체에서 전역적으로 사용하는 함수
    • 개발자들끼리 약속된 것 같다. 누구는 클래스의 메소드를 메소드라하고, 누구는 함수라 하고, 누구는 펑션이라 한다면 의사소통이 비효율적일 것이기 때문에, 약속(?)한 것이 아닐까
    • 나도 이때부터 확실히 머리속에 박아두고 설명할 때는 인지하며 말하는 편이다.
//매개변수가 없는 함수
func sayHello(){
	print("Hello, My name is tree")
}

//매개변수가 있는 함수
func sayHello(name: String){
	print("Hello, My name is \(name)")
}

//매개변수의 기본값이 있는 함수
func sayHello(name: String = "tree"){
	print("Hello, My name is \(name)")
}

//반환 타입이 있는 함수
func sayHello(name: String) -> String{
	return "Hello, My name is \(name)"
}

+ 매개변수의 기본값이 있는 매개변수는 뒤로 보내야 한다.

 

입출력 매개변수 사용

  • 순서
    • 전달인자 값 복사
    • 함수 내부에서 값 변경
    • 반환 시점에 변경된 값을 매개변수에 할당
  • inout을 사용하면 값 타입도 참조 타입처럼 사용할 수 있다
  • B.U.T. 메모리 관점에서 안전하지 않기 때문에 사용을 지양한다. -> 이에 대해서도 이후에 작성할 것이다
//보통은 값을 복사하여 매개변수로 전달한다

var arr: [Int] = [1,2,3,4,5]

func abc(_ arr: [Int]){
	arr[0] = 100
}

abc(arr)
print(arr[0]) // 1

//입출력 매개변수 사용
func abc(_ arr: inout [Int]){
	arr[0] = 100
}

abc(&arr)
print(arr[0]) // 100

함수를 데이터 타입으로

- 앞서서 여러 차례 말했 듯이 함수는 일급 시민으로써 사용된다

var someFunction: (Int, Int) -> Int

func addInts(_ a: Int, _ b: Int) -> Int{
	return a+b
}

someFunction = addInts

print(someFunction(1,2)) // 3

someFunction이라는 변수에 addInts라는 함수를 지정하여 사용할 수 있다

B.U.T. 타입이 같아야한다.

 

중첩 함수

말 그대로 함수 내에 함수가 존재하는 것이다.

func function1(_ bool: Bool) -> (Int) -> Int{
	func plus(_ i: Int) -> Int{
    	return i+1
    }
    func minus(_ i: Int) -> Int{
    	return i-1
    }
    
    //삼항 연산자
    // ? 앞의 식이 true면 plus를 false면 minus를 return한다
    return bool ? plus: minus
}

var num: (Int) -> Int = func(true) //plus함수 할당
print(num(1)) // 2

 

이외에도 다양한 함수들이 존재한다

  • 종료되지 않는 함수
    • 반환 타입을 Never로 선언
  • 반환값을 무시 가능한 함수
    • @discardableResult 어노테이션 사용

야곰님의 Swift Programming을 공부하며 혼자 끄적였던 것들을 옮긴다.

Swift를 공부하는 다른 개발자들에게도 0.1만큼의 도움이 되었으면 좋을 것 같다는 마음으로 시작!

 

Swift

- 고차원적 언어

- ARC(자동 참조 카운팅)으로 메모리를 관리한다

  - 자바 기반의 GC와 비슷한 역할을 하지만, 전혀 다르다고 말할 수 있다. 이에 대해서는 이후에 작성할 것임

- Object-C의 동적 객체 모델과 매개변수를 도입했다

 

특징

  • 안전성
    • guard, 옵셔널, 오류처리 등으로 보다 안전하다
    • 타입에 대해 엄격하다 -> 개발자에게는 오히려 불편하지만, 프로그램 관점으로 본다면 안전하다
  • 신속성
  • FP(함수형 프로그래밍) 패러다임을 적용
  • POP(프로토콜 지향 프로그래밍)

함수형

  • 대규모 병렬처리에 유용하다
  • 상태의 변화없이 데이터를 처리할 수 있다
    • 함수형이 아니라면 포인터, 레퍼런스 등이 변경되어 함수 내부 처리에 영향을 준다
      • 즉, 순수함수를 작성하기 힘들다.
  • 함수를 일급시민으로 다룬다.
    • 전달인자(매개변수)로 전달 가능
    • 동적 프로퍼티로 할당 가능
    • 변수나 데이터 구조 내에 할당 가능
    • 반환 값으로 반환 가능
func sum(first: Int) -> (Int) -> Int{
	return { second in
    	return first+second
    }
}

sum(first:10)(5)

해당 메소드처럼 하나의 매개변수만 담을 수 있게 하는 기법을 커링이라 한다.

 

커링이란?

- 여러개의 매개변수를 갖는 함수를 매개변수 하나를 갖는 함수의 나열로 표현

 

프로토콜 지향 프로그래밍 POP

- 뒤~에서 설명

 

 

 

 

 

 

 

 

 

 

 

 

앞선 포스팅에 이어서 작성된다.

앞선 블로그(https://wlgusdn700.tistory.com/28) 에 가면 iOS에서 화면 캡처하는 것을 알 수 있고 그 캡처된 이미지를 UIImage로 불러올 수 있다.

 

나는 이 캡처된 UIImage를 인스타 스토리에 공유할 것이다!

당연히 카카오/구글/페북 developer 사이트에 방법은 나와있다!

developers.facebook.com/docs/instagram/sharing-to-stories 이곳에 가면 있다.

근데 왜 적냐? 코드가 Objective-C 다.... 안드로이드는 java -> kotlin 이 사실상 문법이 비슷비슷해서 이해할 수 있겠는데...

Ob-C를 내가 어떻게 아냐고....ㅜ

사실 Ob-C를 볼줄이라도 아는 사람들은 곧바로 Swift로 변환이 가능할 것이다. 나도 Objective-C 문법 블로그를 찾아 보면서 변환했다.

 

func backgroundImage(backgroundImage: UIImage) {
        if let urlScheme = URL(string: "instagram-stories://share") {
            if UIApplication.shared.canOpenURL(urlScheme) {
                let pasteboardItems = [["com.instagram.sharedSticker.stickerImage": backgroundImage.pngData(),
                                        "com.instagram.sharedSticker.backgroundImage": backgroundImage.pngData()]]

                let pasteboardOptions = [UIPasteboard.OptionsKey.expirationDate: Date().addingTimeInterval(60 * 5)]

                UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions)

                UIApplication.shared.open(urlScheme as URL, options: [:], completionHandler: nil)
            } else {
                print("인스타 앱이 깔려있지 않습니다.")
            }
        }
    }

코드는 굉장히 간단하다

url로 인스타 앱 중 스토리로 공유하는 화면?을 열것이다.

우선 해당 url을 iOS App에서 열수 있는지 확인을 한다. 인스타 앱이 안깔려있어도 못 여는 것 같다.

pasteboardItems 에는 좀 요상한 자료구조가 담긴다. Array(Dictionary) 이런 형태다.

그리고 문자열에서 유추할 수 있듯, sticker와 background가 있는데, 말그래도 배경과 스티커라고 생각하면 된다.

 

pasteboardOptions 등 외의 코드는 는 이번주내로 다시 알아볼 것이다.

 

중요한 점!

Instagram의 맞춤 URL 스키마를 허용 리스트에 등록

앱에서 Instagram의 맞춤 URL 스키마를 사용하려면 허용 리스트에 추가해야 합니다. 이를 위해서는 앱의 Info.plist에 있는 LSApplicationQueriesSchemes 키에 instagram-stories를 추가합니다.

 

라고 Facebook Developer 에 적혀있다. 따라하면 된다.

Info.plist 에 들어가서 LSApplicationQueriesSchemes를 추가하고 해당 value에 "instagram-stories"를 넣으면 된다.

** value는 Array형태로 넣어야한다

 

안드로이드에서는 manifest에 Internet만 허용해주면 대부분의 url에는 접근이 가능했던 것 같은데, iOS는 따로따로 지정해줘야하나보다... 확실히 apple이 보안/정보 측면에서 강도 높게 설정하고 유지하고 있다고 다시 생각하게 되었다.

 

 

'iOS > SwiftUI' 카테고리의 다른 글

[iOS] SwiftUI 에서 Screen Capture 후 Share  (2) 2021.01.13

+ Recent posts