React-native-iap: ์„ฑ๊ณต์ ์ธ ๊ตฌ๋งค์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  buySubscription์€ E_UNKNOWN์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2018๋…„ 10์›” 13์ผ  ยท  30์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dooboolab/react-native-iap

react-native-iap ๋ฒ„์ „

2.2.2 (iOS์—์„œ # 279๋กœ ์ธํ•ด ์ตœ์‹  ๋ฒ„์ „์ด ์‹คํŒจํ•˜๊ธฐ ๋•Œ๋ฌธ์—)

์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ํ”Œ๋žซํผ (IOS ๋˜๋Š” Android ๋˜๋Š” ๋‘˜ ๋‹ค?)

iOS

์˜ˆ์ƒ๋˜๋Š” ํ–‰๋™

์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ๋งค ์„ฑ๊ณต (์‹ค์‹œ๊ฐ„ ๋ฐ ์ƒ์‚ฐ ์ค‘)

์‹ค์ œ ํ–‰๋™

Promise์—์„œ E_UNKNOWN ์˜ค๋ฅ˜๊ฐ€ ๋ฐ˜ํ™˜ ๋จ
Sentry.io ์˜ค๋ฅ˜ ์ถ”์ ์€ ๋‹ค์Œ์„๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

{"framesToPop":1,"code":"E_UNKNOWN","nativeStackIOS":["0   LuCoaching                          0x000000010062f6fc LuCoaching + 1996540","1   LuCoaching                          0x000000010060aa98 LuCoaching + 1845912","2   LuCoaching                          0x00000001007cad98 __cxa_throw + 438380","3   LuCoaching                          0x00000001007cc62c __cxa_throw + 444672","4   libdispatch.dylib                   0x000000019d078484 <redacted> + 16","5   libdispatch.dylib                   0x000000019d025610 <redacted> + 56","6   LuCoaching                          0x00000001007cc46c __cxa_throw + 444224","7   libdispatch.dylib                   0x000000019d0776c8 <redacted> + 24","8   libdispatch.dylib                   0x000000019d078484 <redacted> + 16","9   libdispatch.dylib                   0x000000019d0249ec <redacted> + 1068","10  CoreFoundation                      0x000000019d5ce1bc <redacted> + 12","11  CoreFoundation                      0x000000019d5c9084 <redacted> + 1964","12  CoreFoundation                      0x000000019d5c85b8 CFRunLoopRunSpecific + 436","13  GraphicsServices                    0x000000019f83c584 GSEventRunModal + 100","14  UIKitCore                           0x00000001ca444bc8 UIApplicationMain + 212","15  LuCoaching                          0x000000010044d110 LuCoaching + 20752","16  libdyld.dylib                       0x000000019d088b94 <redacted> + 4"],"userInfo":{"NSLocalizedDescription":"Verbindung mit iTunes Store nicht mรถglich"},"domain":"SKErrorDomain","line":26,"column":1877,"sourceURL":"/var/containers/Bundle/Application/818C8439-E250-42E8-AD57-EC4FB5FE5547/LuCoaching.app/main.jsbundle"}

ํ…Œ์ŠคํŠธ ๋œ ํ™˜๊ฒฝ (์—๋ฎฌ๋ ˆ์ดํ„ฐ? ์‹ค์ œ ์žฅ์น˜?)

์‹ค์ œ ์žฅ์น˜. ๋ผ์ด๋ธŒ ๊ณ ๊ฐ. ๋งค์šฐ ์ผ๊ด€์„ฑ์žˆ๋Š” ์‹คํŒจ

ํ–‰๋™์„ ์žฌํ˜„ํ•˜๋Š” ๋‹จ๊ณ„

Sandbox ์‚ฌ์šฉ์ž์™€ ํ•จ๊ป˜ ์ ˆ์ฐจ๋ฅผ ํ…Œ์ŠคํŠธ ํ•  ๋•Œ ์˜ค๋ฅ˜๋ฅผ ์žฌํ˜„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๐Ÿ› bug ๐Ÿ“ฑ iOS

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

: +1 : ์šฐ๋ฆฌ๋Š”์ด ๋ฌธ์ œ๋ฅผ ์ž˜ ๊ฒฝํ—˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์•ฝ 10 %์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐœ์ƒํ•˜๊ณ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š”์ด ์ฒญ์ทจ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ ํ•˜์ง€๋งŒ ๊ถ๊ทน์ ์œผ๋กœ ์ด๊ฒƒ์ด ํ›Œ๋ฅญํ•œ ํ•ด๊ฒฐ์ฑ…์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @hyochan ์ด๊ฒƒ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ๋” ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  30 ๋Œ“๊ธ€

@ Gaia-Nutrition์ด ์˜ค๋ž˜๋œ ๋ฌธ์ œ๋ฅผ ํ™•์ธ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ฐ™์€ ์›์ธ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/dooboolab/react-native-iap/issues/201

# 201์˜ @JJMoon ์˜ค๋ฅ˜๋Š” E_DEVELOPER_ERROR ์ด๊ณ  getSubscriptions() ์‚ฌ์šฉํ•˜์—ฌ validProducts ๋ชฉ๋ก์„ ์ฑ„์šฐ์ง€ ์•Š์•„ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ฒดํฌ ์•„์›ƒ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์— ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ด์ œ ์ƒ๊ฐํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งค๋ฅผ ์›ํ•˜๋Š”์ง€ ๋‹ค์‹œ ๊ณ ๋ คํ•˜์—ฌ getSubscriptions() ์™€ buySubscription() ํ†ตํ™” ์‚ฌ์ด์— ์ƒ๋‹นํ•œ ์‹œ๊ฐ„ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ ๋™์•ˆ ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์„ค์ •๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํŽธ์ง‘ :ํ•˜์ง€๋งŒ ๋‹ค์‹œ ๊ตฌ๋งค๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ๋ฌธ์ œ๋Š” ์•ฑ ์Šคํ† ์–ด ์‘๋‹ต์ด ์ฒ˜๋ฆฌ๋˜๋Š” ๊ณณ์ด์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”,

"buyProductWithoutFinishTransaction"๋˜๋Š” "buyProduct"์™€ ๋™์ผํ•œ ๋ฌธ์ œ ๋™์ž‘.

๋ฒ„์ „ 2.2.1

์ €์žฅ๋œ ๋ฐ˜ํ’ˆ์€
{ "framesToPop": 1, "code": "E_UNKNOWN", "nativeStackIOS": [...], "userInfo": { "NSLocalizedDescription": "Connexion ร  lโ€™iTunes Store impossible" }, "domain": "SKErrorDomain", "line": 16, "column": 1599, "sourceURL": "..." }

์ด ๋ฒ„๊ทธ๋ฅผ ์ด์ „ ๋ฒ„์ „์œผ๋กœ ํ”„๋กœ๋•์…˜์—์„œ ์žฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“ˆ์„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

ํฅ๋ฏธ๋กœ์šด ๋ถ€๋ถ„์€ ์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋‚ด ์‚ฌ์šฉ์ž์—๊ฒŒ๋„ ๋ณต์› ๊ตฌ๋งค๊ฐ€ ์‹คํŒจํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. iOS ์‚ฌ์šฉ์ž์˜ ์•ฝ 1 %์—๊ฒŒ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@fierysolid ๊ฐ™์€ ๊ฒฝ์šฐ, ์šฐ๋ฆฌ๋Š” ์‹คํŒจํ•œ iOS ๊ตฌ๋งค์˜ ์•ฝ 5 %์ž…๋‹ˆ๋‹ค. ๊ณ ๊ฐ์ด ๋‹ค์‹œ ๊ตฌ๋งคํ•˜๋ ค๊ณ ํ•˜๋ฉด ๋ณต์› ๊ตฌ๋งค ํŒ์—…์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„. ์˜ค๋Š˜ ์ƒˆ ๋ฒ„์ „ ์ธ 2.3.15 ์—์„œ ์ˆ˜์ •๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. iOS์—์„œ NSDictionary ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ˆœ์ „ํžˆ ์‚ฌ์šฉํ•˜๊ธฐ์— ์•ˆ์ „ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋™์ž‘์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์œผ๋ฉฐ ์ด์ œ ๋ชจ๋“  ์žฅ์น˜์—์„œ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ํ…Œ์ŠคํŠธํ•˜์‹ญ์‹œ์˜ค.

๋ฌธ์ œ๊ฐ€ ๊ณ„์†๋˜๋ฉด ๋‹ค์‹œ์—ฌ์‹ญ์‹œ์˜ค.

๋ฟก ๋นต๋€จ
iPhone 6S๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ƒŒ๋“œ ๋ฐ•์Šค ํ…Œ์Šคํ„ฐ ์‚ฌ์šฉ์ž์™€ buySubscription() ์„ ์‚ฌ์šฉํ•˜๋Š” ๋™์•ˆ ์—ฌ์ „ํžˆ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

{"userInfo":{"NSLocalizedDescription":"Cannot connect to iTunes Store"}}

@danrevah 2.3.15 ์ƒˆ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ด ๋ณด์…จ๋‚˜์š” ? @JJMoon ํ•œ ๋ฒˆ ๋” ํ…Œ์ŠคํŠธ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@dooboolab yes ํ•ด๋‹น ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@danrevah 2.3.16 ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.

@dooboolab ํ•œ ๋ฒˆ ์ž‘๋™ํ–ˆ์ง€๋งŒ ๋‹ค์‹œ ์‹œ๋„ํ•˜๋Š” ๋™์•ˆ์ด ์˜ค๋ฅ˜๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. (v 2.3.17 ์‚ฌ์šฉ)

@JJMoon ์ด๊ฒƒ์— ๋Œ€ํ•œ ๋‹จ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋Š” iPhone6S๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค. cc @JJMoon

๋” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด์ด ๋ฌธ์ œ์— ํˆฌํ‘œํ•œ๋‹ค๋ฉด ์šฐ๋ฆฌ๋Š” ๋” ๊นŠ์ด ํŒŒํ—ค ์น˜๊ธฐ ์œ„ํ•ด ๋” ์—ด์‹ฌํžˆ ๋…ธ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@danrevah ์ด ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.
https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html#//apple_ref/doc/uid/TP40008267 -CH7-SW6
์ƒŒ๋“œ ๋ฐ•์Šค ๋ชจ๋“œ์—์„œ ๊ตฌ๋…์„ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด ์ž ์‹œ ํ›„ ๊ตฌ๋…์„ ๋‹ค์‹œ ๊ตฌ๋งคํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๋‹ค์‹œ ๊ตฌ๋งคํ•˜๋ ค๋ฉด ์ทจ์†Œํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  Apple ์ƒŒ๋“œ ๋ฐ•์Šค ์„œ๋ฒ„์—์„œ ์ด์ƒํ•œ ๋ฐ˜์‘์ด์žˆ์–ด ํ…Œ์ŠคํŠธ๋ฅผ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

@JJMoon ์ผ€์ด์Šค๊ฐ€ ๋ฟก๋ฟก

@JJMoon ๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ํ•ด๊ฒฐ์ฑ…? buySubscription์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ ์ง€๋ถˆ์ด ์ฐจ๊ฐ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ํ™•์ธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
์ซ‘๋ผ๋ฆฌ

+1 ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค

buySubscription ์—์„œ๋„ addAdditionalSuccessPurchaseListenerIOS ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์‹ญ์‹œ์˜ค. ์ด๊ฒƒ์€ # 307๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

buySubscription ์—์„œ๋„ addAdditionalSuccessPurchaseListenerIOS ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์‹ญ์‹œ์˜ค. ์ด๊ฒƒ์€ # 307๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ ์ด๋ฏธ ํ”„๋กœ๋•์…˜์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

@hyochan , ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

if (subscription && subscription.success) {
      this.props.subscribe(subscription.result);
    } else {
      if (Platform.OS === 'ios') {
        const sub = RNIap.addAdditionalSuccessPurchaseListenerIOS(async (purchase) => {
          this.props.subscribe(purchase); // -> This code is never fired
          sub.remove();
        });
      }
    }

@cbfranca ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๋”ฐ๋ฅด์‹ญ์‹œ์˜ค. promises ๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ฝ์† ๊ฑฐ๋ถ€ ํ›„ addAdditionalSuccessPurchaseListenerIOS ์„ ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ถ”๊ฐ€ Platform.OS === 'ios' ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํšจ์ฐฌ
๋ฌด์ง€ํ•ด์„œ ๋ฏธ์•ˆํ•˜์ง€๋งŒ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋งž๊ฒŒ ์˜ˆ์ œ์˜ ๋™์ผํ•œ ๊ธฐ์ค€์„ ๋”ฐ๋ž์Šต๋‹ˆ๋‹ค. async / await๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ์ด ์•ฝ์†์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ถ”์ƒํ™”๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ๋… ๊ฐœ์ฒด๋Š” ๋‚ด ์ถ”์ƒํ™”์— ์˜ํ•ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

static purchaseSubscription(newSubscriptionID, currentSubscriptionID) {
    if (Platform.OS === 'ios') {
      const purchaseResult = KinvoBilling.purchaseSubscriptionIOS(newSubscriptionID);
      return purchaseResult;
    }

    const purchaseResult = KinvoBilling.purchaseSubscriptionANDROID(newSubscriptionID, currentSubscriptionID);
    return purchaseResult;
  }

  static purchaseSubscriptionANDROID = async (newSubscriptionID, currentSubscriptionID) => {
    const hasCurrentSubscription = currentSubscriptionID !== null;

    if (hasCurrentSubscription) {
      const purchaseResult = KinvoBilling.updateSubscription(newSubscriptionID, currentSubscriptionID);
      return purchaseResult;
    }
    const purchaseResult = KinvoBilling.buySubscription(newSubscriptionID);
    return purchaseResult;
  }

  static purchaseSubscriptionIOS = async (subscriptionID) => {
    await KinvoBilling.getSubscriptions();
    const purchaseResult = await KinvoBilling.buySubscription(subscriptionID);

    return purchaseResult;
}

๋ฟก๋ฟก
```
static purchaseSubscriptionIOS = ๋น„๋™๊ธฐ (subscriptionID) => {
KinvoBilling.getSubscriptions ();๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
{
const purchaseResult = KinvoBilling.buySubscription (subscriptionID);
} catch (err) {
const ๊ตฌ๋… = RNIap.addAdditionalSuccessPurchaseListenerIOS (async (purchase) => {
// dooboolab => ์—ฌ๊ธฐ์—์„œ ํ˜ธ์ถœ์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
this.setState ({์˜์ˆ˜์ฆ : purchase.transactionReceipt}, () => this.goToNext ());
subscription.remove ();
}
}
return purchaseResult;
}
````

์œ„์˜ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๋ผ์ดํ”„ ์‚ฌ์ดํด์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@hyochan ๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์›”๊ฐ„ ๊ตฌ๋… ํ”Œ๋žœ ๊ตฌ๋งค-ํ™•์ธ
  • ์—ฐ๊ฐ„ ๊ตฌ๋… ํ”Œ๋žœ์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ-์‹คํŒจ ๋ฐ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ

๋˜ ๋‹ค๋ฅธ ์˜์‹ฌ : ๊ตฌ๋…์—์„œ๋„ finishTransaction ()์„ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

์ด ์˜ค๋ฅ˜๋„ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์žฌํ˜„ํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

react-native-iap ๋ฒ„์ „

^ 2.4.1

๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฒ„์ „

https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz

ํ”Œ๋žซํผ

iOS, ์‹ค์ œ ์žฅ์น˜์—์„œ TestFlight์—์„œ ํ…Œ์ŠคํŠธ ํ•  ๋•Œ.

๊ด€์ฐฐ

๋‚ด ์•ฑ์—์„œ RNIap ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด iOS๊ฐ€ ์ด์ „ iTunes / App Store ์‚ฌ์šฉ์ž (์ดํ›„ ๋กœ๊ทธ ์•„์›ƒํ•˜๊ณ  iOS ์„ค์ •์„ ํ†ตํ•ด ๋Œ€์ฒด)์˜ ์•”ํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์˜จ๋ผ์ธ ์–ด๋”˜๊ฐ€์—์„œ ์ด๊ฒƒ์ด ๋•Œ๋•Œ๋กœ iPhone ์‚ฌ์šฉ์ž๋ฅผ ๊ดด๋กญํžˆ๋Š” ๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ํ•˜๋‚˜์˜ iTunes ๊ณ„์ •์œผ๋กœ ์•ฑ์„ ๊ตฌ์ž… ํ•œ ๋‹ค์Œ ์ „ํ™”๊ฐ€ ์ƒˆ iTunes ๊ณ„์ •์œผ๋กœ ์ „ํ™˜๋˜์ง€๋งŒ ์•ฑ์€ ๊ณ„์†ํ•ด์„œ ์•”ํ˜ธ๋ฅผ ๋ฌป์Šต๋‹ˆ๋‹ค. ์ด์ „ iTunes ๊ณ„์ •.

๋‚ด ์•ฑ (๋ฐ TestFlight)์„ ์‚ญ์ œํ•˜๊ณ  ์ƒˆ App Store ์‚ฌ์šฉ์ž๋กœ ๋‹ค์‹œ ์„ค์น˜ํ•˜๋ ค๊ณ ํ–ˆ์ง€๋งŒ ์•„๋ฌด ์†Œ์šฉ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋™์ž‘์„ ์ œ๊ฑฐ ํ•  ์ˆ˜์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ์žฅ์น˜๋ฅผ ์ง€์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•œ ํ›„์—๋Š” ๋” ์ด์ƒ์ด ์˜ค๋ฅ˜๋ฅผ ์žฌํ˜„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์‹ค์ œ ํ–‰๋™

  1. buySubscription ()
  2. iOS ๋ชจ๋‹ฌ "๊ตฌ๋… ์กฐ๊ฑด"์ด ํ‘œ์‹œ๋˜๋ฉด ๊ณ„์†์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  3. iOS ๋ชจ๋‹ฌ "๊ตฌ๋… ํ™•์ธ"์ด ํ‘œ์‹œ๋˜๋ฉด ํ™•์ธ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  4. buySubscription ()์—์„œ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜ :
{
   code: E_UNKNOWN, 
   column: 1565, 
   domain: NSURLErrorDomain, 
   framesToPop: 1, 
   line: 20, 
   nativeStackIOS: [...],
   sourceURL: ...,
   userInfo: {
      _kCFStreamErrorCodeKey: -4, 
      _kCFStreamErrorDomainKey: 4, 
      NSErrorFailingURLKey: None, 
      NSErrorFailingURLStringKey: https://p100-sandbox.itunes.apple.com/WebObjects/MZFinance.woa/wa/inAppBuy, 
      NSLocalizedDescription: Cannot connect to iTunes Store, 
      NSUnderlyingError: {
         code: "-1005", 
         domain: "kCFErrorDomainCFNetwork", 
         message: "underlying error", 
         nativeStackIOS: [...],
         userInfo:{"NSErrorPeerAddressKey":null,"_kCFStreamErrorCodeKey":-4,"_kCFStreamErrorDomainKey":4}
      }
   }
}

ํ–‰๋™์„ ์žฌํ˜„ํ•˜๋Š” ๋‹จ๊ณ„

  1. App Store Connect์—์„œ ํ…Œ์ŠคํŠธ ์‚ฌ์šฉ์ž ๋งŒ๋“ค๊ธฐ
  2. App Store์—์„œ ์•ฑ ์„ค์น˜ (๋˜๋Š” ํ…Œ์ŠคํŠธ ์‚ฌ์šฉ์ž๋ฅผ TestFlight์— ์ดˆ๋Œ€ํ•˜๊ณ  TestFlight๋ฅผ ์„ค์น˜ ํ•œ ๋‹ค์Œ TestFlight๋ฅผ ํ†ตํ•ด ์•ฑ)
  3. ์•ฑ์—์„œ ๊ตฌ๋… ๊ตฌ๋งค
  4. ๊ตฌ๋… ๋งŒ๋ฃŒ
  5. iOS Apple ID ๋กœ๊ทธ ์•„์›ƒ (์„ค์ •> Apple ID, ๋กœ๊ทธ ์•„์›ƒ)
  6. ์ƒˆ Apple ID ๋กœ๊ทธ์ธ
  7. ์•ฑ์—์„œ ๊ตฌ๋… ๊ตฌ๋งค

์ด๊ฒƒ์ด ๋ˆ„๊ตฐ๊ฐ€๋ฅผ ๋•๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค!

ํšจ์ฐฌ

๋งŽ์€ ๊ฒƒ์„ ์‹œ๋„ํ•œ ํ›„์—๋„ ์—ฌ์ „ํžˆ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ์—์„œ RNIap.buySubscription (sku)์€ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ํ•ด๊ฒฐ ํ–ˆ๋‚˜์š”?

```
static purchaseSubscriptionIOS = ๋น„๋™๊ธฐ (subscriptionID) => {
KinvoBilling.getSubscriptions ();๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

try {
  const purchaseResult = await RNIap.buySubscription(subscriptionID);
  return createResponse(true, purchaseResult);
} catch (error) {
  const subscription = RNIap.addAdditionalSuccessPurchaseListenerIOS(async (purchase) => {
    // dooboolab => check the call here.
    console.tron.log('--- ERROR ----');
    console.tron.log(error);
    console.tron.log('--- PURCHASE ----');
    console.tron.log(purchase);
    const result = purchase;
    subscription.remove();
    console.tron.log(result);

    if (result) {
      return createResponse(true, result);
    }
    return createResponse(false, result);
  });
}

};
```

: +1 : ์šฐ๋ฆฌ๋Š”์ด ๋ฌธ์ œ๋ฅผ ์ž˜ ๊ฒฝํ—˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์•ฝ 10 %์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐœ์ƒํ•˜๊ณ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š”์ด ์ฒญ์ทจ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ ํ•˜์ง€๋งŒ ๊ถ๊ทน์ ์œผ๋กœ ์ด๊ฒƒ์ด ํ›Œ๋ฅญํ•œ ํ•ด๊ฒฐ์ฑ…์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @hyochan ์ด๊ฒƒ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ๋” ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

3.4.6์—์„œ๋„ ๋งค์šฐ ์œ ์‚ฌํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. E_UNKOWN ์ฒซ ๋ฒˆ์งธ ๊ตฌ๋งค ์‹œ๋„๊ฐ€ ์‹คํŒจํ•˜๊ณ  ์žฌ ์‹œ๋„๊ฐ€ ์„ฑ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ์—๊ฒŒ ์ด๊ฒƒ์€ buyProduct ๊ฐ€ ์•„๋‹ˆ๋ผ buySubscription ํ•ฉ๋‹ˆ๋‹ค. @hyochan ์ด ์—ฌ์ „ํžˆ ๋™์ผํ•œ ๊ทผ๋ณธ ์›์ธ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์•ˆ๋…•ํ•˜์„ธ์š”! RNIap.requestSubscription ()์„ ํ˜ธ์ถœ ํ•œ ํ›„์—๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ํ‘œ์‹œ๋˜์ง€๋งŒ ๊ฒฐ์ œ๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด ์‹ ์šฉ ์นด๋“œ์— ์š”๊ธˆ์ด ์ฒญ๊ตฌ๋ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ๊ณผ๊ฑฐ๋ฅผ ์–ป๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๊ตฌ๋งค๋ฅผ ๋ณต์›ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ˆ„๊ตฌ๋“ ์ง€ ์ด๊ฒƒ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์–ป์—ˆ์Šต๋‹ˆ๊นŒ? ๋ฒ„์ „ 3.5.9๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰