Published on

๐Ÿ“ฑ iOS - ์ธ์Šคํƒ€๊ทธ๋žจ ์Šคํ† ๋ฆฌ๋กœ ๊ณต์œ ํ•˜๊ธฐ

Authors
  • avatar
    Name
    ์ด์ฐฝ์ค€
    Twitter

์ธ์Šคํƒ€๊ทธ๋žจ ์Šคํ† ๋ฆฌ ๊ณต์œ 

์˜ค๋Š˜์€ ์•ฑ์—์„œ ์–ป์–ด๋‚ธ ์‚ฌ์ง„์„ ์ธ์Šคํƒ€๊ทธ๋žจ ์Šคํ† ๋ฆฌ๋กœ ๊ณต์œ ํ•˜๋Š” ๋ฒ•์„ ๊ณต๋ถ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Instagram - Sharing to stories

ํ•ด๋‹น ๋ฌธ์„œ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ์ง„ํ–‰ํ•ด๋ณด์ฃ !

์•ฑ ID ํœ™๋“ํ•˜๊ธฐ

๊ฐ€์žฅ ๋จผ์ € ๋ˆˆ์— ๋„๋Š” ๊ฒฝ๊ณ ๋ฌธ์ด ์žˆ๋„ค์š”!

๋‹ค๋ฅธ SDK์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์•ฑ ๋“ฑ๋ก์„ ํ•ด์•ผํ•˜๋‚˜ ๋ด…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ 1์›”๋ถ€ํ„ฐ๋ฉด ๊ทธ ์ „์—๋Š” ๊ทธ๋ƒฅ ๋๋˜๊ฑด๊ฐ€โ€ฆ?

Meta ๊ฐœ๋ฐœ์ž ๊ณ„์ •์„ ๋งŒ๋“ค๊ณ  ์•ฑ์„ ์ƒ์„ฑํ•ด์ฃผ๋ฉด ์ด๋ ‡๊ฒŒ ์•ฑ ID๋ฅผ ์–ป์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ค ์ด๋ฏธ์ง€๋ฅผ ์ œ๊ณตํ•ด์•ผํ• ์ง€ ํ™•์ธํ•ด๋ณด๊ธฐ

๊ทธ๋Ÿฌ๋ฉด ์ด์ œ ์ธ์Šคํƒ€ ์Šคํ† ๋ฆฌ๋กœ ์˜ฌ๋ฆด ๋‚ด์šฉ์„ ์ œ๊ณตํ•˜๋ ค๋ฉด ์–ด๋–ค ๊ฒƒ์ด ํ•„์š”ํ•œ์ง€๋ฅผ ์•Œ์•„์•ผ๊ฒ ์ฃ ?

์ด ํ•ญ๋ชฉ์„ ์‚ดํŽด๋ณด๋ฉด ์Šคํ† ๋ฆฌ๋Š” Background Layer์™€ Sticker Layer๋กœ ๊ตฌ๋ถ„๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ† ๋ฆฌ์˜ ๋ฐฐ๊ฒฝ์„ ๊ฝ‰ ์ฑ„์šด ์ƒํƒœ๋กœ ๊ณ ์ •์‹œํ‚ค๋Š” ์ด๋ฏธ์ง€๋Š” Background Layer๋กœ, ์œ ์ €๊ฐ€ ๋ณ€ํ˜•ํ•˜๊ฑฐ๋‚˜ ์ด๋™์‹œ์ผœ ๋ฐฐ์น˜์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ด๋ฏธ์ง€๋Š” Sticker Layer๋กœ ๊ตฌ์„ฑํ•ด์ฃผ๋ฉด ๋˜๊ฒ ์ฃ ?

๊ทธ๋Ÿฌ๋ฉด ์–ด๋–ป๊ฒŒ ์ธ์Šคํƒ€๊ทธ๋žจ ์•ฑ์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ „๋‹ฌํ•ด์ค„ ์ˆ˜ ์žˆ์„๊นŒ์š”?

์Šคํ‚ค๋งˆ ์ ์šฉ

์•ฑ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ธ์Šคํƒ€๊ทธ๋žจ์œผ๋กœ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„ธ ๊ฐ€์ง€ ์Šคํ…์„ ๊ฑฐ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. ์•ฑ์ด ์ธ์Šคํƒ€๊ทธ๋žจ์˜ ๋งž์ถค URL ์Šคํ‚ค๋งˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  2. ํŽ˜์ด์ŠคํŠธ๋ณด๋“œ์— ๊ณต์œ ํ•˜๊ณ ์ž ํ•˜๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
  3. ์•ฑ์—์„œ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๋งž์ถค URL ์Šคํ‚ค๋งˆ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์—ญ์‹œ ์‹œ์ž‘์€ ๋‹ค๋ฅธ SDK์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์•ฑ์— URL ์Šคํ‚ค๋งˆ๋ฅผ ๋“ฑ๋กํ•ด์ฃผ๋Š” ๊ฒƒ์ด๊ฒ ์ฃ ?

์ธ์Šคํƒ€๊ทธ๋žจ์€ Info.plist ํŒŒ์ผ์— ์žˆ๋Š” LSApplicationQueriesSchemasํ‚ค์— instagram-stories๋ฅผ ์ถ”๊ฐ€ํ•ด๋‹ฌ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ํ•  ์ ์€ Array ํƒ€์ž…์œผ๋กœ ๊ทธ ํ•˜์œ„์— ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ธ์Šคํƒ€๊ทธ๋žจ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์ด๋‚˜ ์•ฑ๋“ค์˜ ์Šคํ‚ค๋งˆ๋“ค๋„ ๋“ฑ๋ก๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ !

์ฝ”๋“œ ์ž‘์„ฑ

์ด์ œ ์ธ์Šคํƒ€๊ทธ๋žจ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

๋ฌธ์ œ๋Š” ์ธ์Šคํƒ€๊ทธ๋žจ์ด ์˜ˆ์ œ๋กœ Swift ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ Obj-C ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด์š”..

์ƒ๋‹นํžˆ ๋‹นํ™ฉ์Šค๋Ÿฝ์ง€๋งŒ.. ์•Œ์ž˜๋”ฑ์œผ๋กœ Swift๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.. ๐Ÿ˜ก

์šฐ๋ฆฌ์—๊ฒ ์ด์ œ GPT๋ผ๋Š” ๋ฌด๊ธฐ๋„ ์žˆ์œผ๋‹ˆ๊นŒ์š”!

์šฐ์„  ์ „๋‹ฌํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์™€ ํƒ€์ž…, ์„ค๋ช…์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ฐฐ๊ฒฝ ์ž์‚ฐ ๊ณต์œ ํ•˜๊ธฐ

์ด๋ฆ„์„ ๋ณด์•„ํ•˜๋‹ˆ Background Layer๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ๋งํ•˜๋Š” ๊ฒƒ์ด๊ฒ ์ฃ ?

ChatGPT์—๊ฒŒ Obj-C ์–ธ์–ด๋ฅผ Swift๋กœ ๋ณ€ํ™˜ํ•ด๋‹ฌ๋ผ๊ณ  ํ•˜๋‹ˆ ๊ฝค ๊ทธ๋Ÿด๋“ฏ ํ•ด๋ณด์ด๋Š” ์ฝ”๋“œ๊ฐ€ ๋‚˜์™€์„œ ๊ทธ๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์ ์šฉํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

  private func shareToInstagram() {
    if
      let backgroundImage = UIImage(named: "GiftMock"), // ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ž„์‹œ ๋ฐ์ดํ„ฐ
      let imageData = backgroundImage.pngData() { // 1๏ธโƒฃ
      self.backgroundImage(backgroundImage: imageData, appID: URLSchemes.instagramStory.url)
    }
  }

  private func backgroundImage(backgroundImage: Data, appID: String) {
    if let url = URL(string: appID) {
      if UIApplication.shared.canOpenURL(url) { // 2๏ธโƒฃ
        let pasteboardItems = [["com.instagram.backgroundImage": backgroundImage]]
        let pasteboardOptions: [UIPasteboard.OptionsKey: Any] = [
          .expirationDate: Date(timeIntervalSinceNow: 60 * 5)
        ]
        UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions) // 3๏ธโƒฃ
        UIApplication.shared.open(url, options: [:]) // 4๏ธโƒฃ
      } else {
        // Error Handling
      }
    }
  }

๊ณผ์ •์€ ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

  1. ์ธ์Šคํƒ€๊ทธ๋žจ์ด ์š”๊ตฌํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ํƒ€์ž…์„ ๋งž์ถฐ์ฃผ๊ธฐ ์œ„ํ•ด UIImage ํŒŒ์ผ์„ Data ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค.
  2. ์Šคํ‚ค๋งˆ URL์ด ์œ ํšจํ•œ ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์— ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์Šคํ‚ค๋งˆ๊ฑฐ๋‚˜ ๊ธฐ๊ธฐ์— ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์€ ์•ฑ์œผ๋กœ ์—ฐ๊ฒฐ ์‹œ ์—๋Ÿฌ๋ฅผ ๋˜์ ธ๋ƒ…๋‹ˆ๋‹ค.
  3. ๋ณ€ํ™˜ํ•œ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ UIPasteboard๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณต์‚ฌํ•ด ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. .expirationDate๋ฅผ ํ†ตํ•ด ์ €์žฅ ๊ธฐ๊ฐ„์„ ์„ค์ •ํ•ด์ฃผ์—ˆ๋„ค์š”.
  4. URL ์Šคํ‚ค๋งˆ๋ฅผ ์—ด๊ณ  ์ธ์Šคํƒ€๊ทธ๋žจ ์•ฑ์˜ ์Šคํ† ๋ฆฌ ์ถ”๊ฐ€ ํ™”๋ฉด์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๊ณผ์—ฐ ๊ฒฐ๊ณผ๋Š”!

  • Info.plist URL ๋“ฑ๋ก ์—๋Ÿฌ

๐Ÿ˜.. ํ•œ ๋ฒˆ์— ๋  ๋ฆฌ๊ฐ€ ์—†์ฃ โ€ฆ

๋ฌธ์ œ๋Š” ์ด๊ณณ์— ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ถ„๋ช… LSApplicationQuriesSchemas๋ฅผ ๋“ฑ๋กํ•˜๋ผ๊ณ  ํ–ˆ์—ˆ๋‹จ ๋ง์ด์ฃ ?

๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋‹ค์‹œ ์ฝ์–ด๋ณด๊ณ  ์ˆ˜ ์ฐจ๋ก€ ์‹œ๋„ํ•ด๋ดค์ง€๋งŒ ์ง„์ „์ด ์—†์–ด ๊ฐ’์„ ๋‹ค์‹œ ๋ณต์‚ฌ-๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋žฌ๋”๋‹ˆ..

์•„๋‹ˆ ๊ธ€์Ž„ ํ‚ค ๊ฐ’์ด ์ž๋™์œผ๋กœ ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค.. ์ „์—๋Š” ๋Œ€์ฒด ์™œ..

์ˆ˜์ •์„ ๋น ๋ฅด๊ฒŒ ํ•ด์ฃผ๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ด…์‹œ๋‹ค. ๊ณผ์—ฐ ์ด๋ฒˆ์—๋Š”..?

  • ๋ฐ์ดํ„ฐ๊ฐ€ ๋„˜์–ด์˜ค์ง€ ์•Š๋Š” ๋ฒ„๊ทธ

์˜ค! ๋ญ”๊ฐ€ ๋˜๋Š” ๊ฒƒ ๊ฐ™์•„์š”! ๐Ÿฅณ

๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ œ๋Š” ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋„˜์–ด์˜ค์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์ฃ โ€ฆ?

๋ฌด์—‡์ด ๋ฌธ์ œ์ผ๊นŒ ๋˜ ์‚ดํŽด๋ณด๋˜ ์ค‘.. ์‚ฌ์†Œํ•œ ์ˆ˜์ •์„ ์ œ๊ฐ€ ์ €์งˆ๋ €๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

let pasteboardItems = [["com.instagram.backgroundImage": backgroundImage]]

๋ฐ”๋กœ ์ด ๋ถ€๋ถ„์ด์—์š”!

key ๊ฐ’์œผ๋กœ "com.instagram.backgroundImage"๋ฅผ ์ฃผ๊ณ  ์žˆ์ฃ ..

ํ•˜์ง€๋งŒ ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด "com.instagram.sharedSticker.backgroundImage"๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค..

์ธ์Šคํƒ€๊ทธ๋žจ ์•ฑ์˜ ์ž…์žฅ์—์„œ ๋ณด๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์œผ๋ ค๊ณ  ์‚ดํŽด๋ณธ key๊ฐ’์— ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋‹ˆ ๋„˜๊ฒจ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒƒ์ด์˜€์ฃ ..

์‚ฌ์‹ค์€ ์ € key๊ฐ’์€ ์ œ ์•ฑ์—์„œ ํด๋ฆฝ๋ณด๋“œ์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ผ์ข…์˜ ID๊ฐ’์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์—ฌ ์ˆ˜์ •์„ ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ โ€œ์ธ์Šคํƒ€๊ทธ๋žจ์ด ์–ด๋–ป๊ฒŒ ๊ฐ’์„ ๋ฐ›์•„์˜ค๋Š”๊ฑธ๊นŒโ€๋ฅผ ์ƒ๊ฐํ•˜๋‹ค๋ณด๋‹ˆ ์ฝ”๋“œ ์ƒ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๋„˜๊ฒจ์ฃผ๋Š” ๋กœ์ง์€ ์–ด๋””์—๋„ ์—†๊ณ  ๋ฐ์ดํ„ฐ์™€ ๊ด€๋ จ๋œ ๊ฐ’์€ ์ € pasteboardItems ๋ฐ–์— ์—†๋”๊ตฐ์š”..

๊ฒฐ๊ตญ์€ key-value๋กœ ์ฐพ์•„๋‚ด๋Š” ๋ฐฉ๋ฒ•๋ฐ–์— ์—†๊ฒ ๋‹ค ์‹ถ์–ด ์ € ๋ถ€๋ถ„์„ ์›๋ž˜๋Œ€๋กœ ์ˆ˜์ •ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์™€! ์„ฑ๊ณต์ด๋„ค์š”!

๋ฐฐ๊ฒฝ์œผ๋กœ ์‚ฌ์ง„์ด ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ‹ฐ์ปค ์ž์‚ฐ ๊ณต์œ ํ•˜๊ธฐ

์—ฌ๊ธฐ๊นŒ์ง€ ์„ฑ๊ณตํ–ˆ๋‹ค๋ฉด ์Šคํ‹ฐ์ปค ๋ ˆ์ด์•„์›ƒ๊นŒ์ง€ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์•„์ฃผ ์‰ฝ์Šต๋‹ˆ๋‹ค.


private func shareToInstagram(background: UIImage?, sticker: UIImage?) {
    if
      let background, let sticker,
      let imageData = background.pngData(),
      let stickerData = sticker.pngData() {
      self.backgroundImage(
        backgroundImage: imageData,
        stickerImage: stickerData,
        appID: URLSchemes.instagramStory.url
      )
    }
  }

  private func backgroundImage(backgroundImage: Data, stickerImage: Data, appID: String) {
    if let url = URL(string: appID) {
      if UIApplication.shared.canOpenURL(url) {
        let pasteboardItems = [
          [
            "com.instagram.sharedSticker.backgroundImage": backgroundImage,
            "com.instagram.sharedSticker.stickerImage": stickerImage // โœจ ์จ”์ž”
          ]
        ]

        let pasteboardOptions: [UIPasteboard.OptionsKey: Any] = [
          .expirationDate: Date(timeIntervalSinceNow: 60 * 5)
        ]
        UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions)
        UIApplication.shared.open(url, options: [:])
      } else {
        // Error Handling
      }
    }
  }

์ด๋ ‡๊ฒŒ key-value๋ฅผ ํ•˜๋‚˜๋งŒ ๋” ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋˜๊ฑฐ๋“ ์š”!

์™„์„ฑ

์ž ์ด๋ ‡๊ฒŒ ์ธ์Šคํƒ€๊ทธ๋žจ ์Šคํ† ๋ฆฌ๋กœ ์›ํ•˜๋Š” ์ด๋ฏธ์ง€๋ฅผ ๊ณต์œ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ณต๋ถ€ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค!

์ƒ๊ฐ๋ณด๋‹ค ๊ต‰์žฅํžˆ ๊ฐ„๋‹จํ–ˆ๋˜ ๊ฒƒ ๊ฐ™์•„์š”!

์ž‘์—…๋ฌผ์„ ๋ฐ”๊นฅ์— ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋ญ”๊ฐ€ ๋ฟŒ๋“ฏํ•œ ๊ณต๋ถ€์˜€์Šต๋‹ˆ๋‹ค. ๐Ÿ˜