React-native-iap: purchaseUpdatedListener๋Š” ์•ฑ ์‹œ์ž‘์‹œ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๊ณ  requestSubscription ํ˜ธ์ถœ ํ›„์—๋Š” ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2020๋…„ 04์›” 21์ผ  ยท  22์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dooboolab/react-native-iap

react-native-iap ๋ฒ„์ „

4.4.6

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

0.61.5

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

iOS

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

purchaseUpdatedListener requestSubscription ํ†ตํ™” ํ›„ ๋งค๋ฒˆ purchaseUpdatedListener requestSubscription ํ†ตํ™”

์‹ค์ œ ํ–‰๋™

purchaseUpdatedListener๋Š” ์•ฑ ์‹œ์ž‘์‹œ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๊ณ  requestSubscription ํ˜ธ์ถœ ํ›„์—๋Š” ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

์‹ค์ œ ์žฅ์น˜

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

readme๋ฅผ ๋”ฐ๋ฅด๊ณ  ๊ตฌ๋…์„ ์š”์ฒญํ•˜์‹ญ์‹œ์˜ค.

๐Ÿ“ฑ iOS ๐Ÿ•ต๏ธโ€โ™‚๏ธ need more investigation ๐Ÿ™ help wanted

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

initConnection() ์ „ํ™”๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์€ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
README๋Š” ์—ฌ๊ธฐ์— ๊ตต์€ ๋ถ€๋ถ„์œผ๋กœ ์—…๋ฐ์ดํŠธ ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

initConnection() iOS์—์„œ๋Š” canMakePayments ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ __ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค .__

"iOS์—์„œ๋Š” canMakePayments๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋งŒํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค."์ด ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•˜๊ณ  ๊ธฐ๋ณธ ์˜ˆ์ œ์— initConnection() ๋„ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์˜ˆ์ œ์— ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ์ด ์„ ํƒ ์‚ฌํ•ญ์ด๋ผ๊ณ  ์ •๋ง๋กœ ํ™•์‹ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ๋งค ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋กํ•˜๊ธฐ ์ „์— initConnection() ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์œผ๋ฏ€๋กœ # 1002 ๋ฐ # 756๊ณผ ๊ด€๋ จ์ด์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? @Strate finishTransaction ํ–ˆ์Šต๋‹ˆ๊นŒ?

@hyochan ์˜ˆ,ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ์ด ํ˜ธ์ถœ์€ ์•ฑ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•œ ํ›„์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@hyochan ์ €๋Š” expo-in-app-purchase ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์•˜์ง€๋งŒ ์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

@Strate ๊ท€ํ•˜์˜ ์ฝ”๋“œ๋ฅผ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ์ ˆ๋Œ€์ ์œผ๋กœ ํ™”๊ฐ€๋‚ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ์ด์ „ ๋ฒ„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? @Strate finishTransaction ํ–ˆ์Šต๋‹ˆ๊นŒ?

๊ตฌ๋งค๊ฐ€ finishTransaction์˜ ์ธ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ• ๊นŒ์š”? ๋”ฐ๋ผ์„œ finishTransaction์— ์ „๋‹ฌํ•  ์ธ์ˆ˜๋ฅผ ๊ฐ€์ ธ ์˜ค๋ ค๋ฉด ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@Sophrinix finishTransaction์ด purchaseUpdatedListener ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœ ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค.

@hyochan ์ฃ„์†กํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ ์‹ค์ œ ์ฝ”๋“œ๊ฐ€์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. expo-in-app-purchase ๋ชจ๋“ˆ๋กœ ์ „ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค. @Sophrinix ๊ฐ€ ๋™์ผํ•œ ๋ฌธ์ œ๋ฅผ ๊ฒฝํ—˜ ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Btw, ๋‚ด ์ฝ”๋“œ์—๋Š” ํŠน๋ณ„ํ•œ ๊ฒƒ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ์‹œ์ž‘ ๋˜ ์ž๋งˆ์ž ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  readme๋ฅผ ๋”ฐ๋ฅด์‹ญ์‹œ์˜ค.

์ด๊ฒƒ์€ ํšŒ๊ท€๋ผ๋Š” ๊ฒƒ์ด ๋ฐํ˜€์กŒ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

"react": "16.8.1",
"react-native": "^0.59.10",
"react-native-iap": "4.3.0",

์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ฌธ์ œ๋Š” ์˜จ๋‹ค react-native-iap 4.4.4 ์™€ ๋ฒ„์ „ react-native ์ด์ „์— 0.60

@Sophrinix ๋ฐฉ๊ธˆ ๋‚ด ํŽธ์—์„œ requestPurchase ์‹œ๋„ํ–ˆ๋Š”๋ฐ ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋˜ํ•œ initConnection ์ „ํ™”๋ฅผํ–ˆ๋Š”์ง€ ๋‹ค์‹œ ํ™•์ธํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ด๋Š” android ์—์„œ์™€ ๊ฐ™์ด iOS ์—์„œ ํ˜ธ์ถœํ•ด์•ผํ•˜๋Š” ์ตœ๊ทผ ์—…๋ฐ์ดํŠธ์˜ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

4.3.0์œผ๋กœ ๋˜ ๋Œ๋ฆฌ๋Š” ๊ฒƒ์ด ์ž‘๋™ ํ•จ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ๋ฏธ์ณ ๊ฐ€๊ณ  ์žˆ์—ˆ๊ณ  ๋ฌธ์ œ๋ฅผ ์ฐพ์œผ๋ ค๊ณ  1 ์‹œ๊ฐ„ ์ด์ƒ ๋””๋ฒ„๊น…ํ–ˆ์Šต๋‹ˆ๋‹ค.

4.3.4 ์—์„œ 4.4.3 ๊นŒ์ง€ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ 4.4.4 ์—์„œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.

4.3.4 ์—์„œ 4.4.3 ๊นŒ์ง€ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ 4.4.4 ์—์„œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ๋„ 4.4.8์—์„œ 4.4.3์œผ๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ๋˜์—ˆ์œผ๋ฉฐ ํ˜„์žฌ ์ž‘๋™ ์ค‘์ž…๋‹ˆ๋‹ค!

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? @Strate finishTransaction ํ–ˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š”์— ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์˜ค์ „ 4.4.0 ํ˜ธ์ถœ๋˜๋Š” ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์˜ ๊ฒƒ๋„ ํฌํ•จ - purchaseErrorSubscription .

๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ์— ๋Œ€ํ•ด ์ฝ์–ด๋ณด์‹ญ์‹œ์˜ค. ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘ : ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๊ตฌ๋งค๊ฐ€ ์ „์†ก๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๊ตฌ๋งค๋ฅผ ์ทจ์†Œ ํ•  ๋•Œ ์ƒํƒœ ๋กค๋ฐฑ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

4.3.0 ์ด ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

RN 0.62.2 ๋ฐ react-native-iap 4.4.8์—์„œ ๋ฉฐ์น  ๋™์•ˆ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
README์˜ ์˜ˆ์ œ์—์„œ ๋ˆ„๋ฝ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— initConnection() ๋†“์ณค์Šต๋‹ˆ๋‹ค.

4.4.8๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•  ๋•Œ iOS์—์„œ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ผ๋ถ€ ๊ตฌ๋…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. 4.4.3์œผ๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ํ˜„์žฌ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. initConnection ()์€ ํ•„์ˆ˜์ž…๋‹ˆ๊นŒ? ์˜์‚ฌ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

initConnection() ์ „ํ™”๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์€ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
README๋Š” ์—ฌ๊ธฐ์— ๊ตต์€ ๋ถ€๋ถ„์œผ๋กœ ์—…๋ฐ์ดํŠธ ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

initConnection() iOS์—์„œ๋Š” canMakePayments ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ __ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค .__

"iOS์—์„œ๋Š” canMakePayments๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋งŒํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค."์ด ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•˜๊ณ  ๊ธฐ๋ณธ ์˜ˆ์ œ์— initConnection() ๋„ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์˜ˆ์ œ์— ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ์ด ์„ ํƒ ์‚ฌํ•ญ์ด๋ผ๊ณ  ์ •๋ง๋กœ ํ™•์‹ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ๋งค ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋กํ•˜๊ธฐ ์ „์— initConnection() ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์œผ๋ฏ€๋กœ # 1002 ๋ฐ # 756๊ณผ ๊ด€๋ จ์ด์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” 4.4.9๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ์ด ํ‹ฐ์ผ“์— ์„ค๋ช… ๋œ ๋ฌธ์ œ๋„ ๋‚˜์—๊ฒŒ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฆฌ์Šค๋„ˆ๋Š” ์‹œ์ž‘๋  ๋•Œ๋งŒ ํ˜ธ์ถœ๋˜์ง€๋งŒ ๋‚ด๊ฐ€ ์„ค์ • ํ•œ ๋‹ค์Œ ๊ตฌ๋งค๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
react-native-iap/index.ts ๋ณด๊ณ  ๋‚ด๋ถ€์—์„œ ์ผ์–ด๋‚˜๋Š” ์ผ์„ ํŒŒ์•…ํ•œ ํ›„ ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ๋ฅผ ์ง์ ‘ ๊ตฌ๋…ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด๋Š” ์–ธ์ œ๋“ ์ง€ ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ง€์†๋ฉ๋‹ˆ๋‹ค. (ํ•œ ๋ฒˆ๋งŒ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค)

import { NativeModules, NativeEventEmitter } from 'react-native';
import { Observable } from 'rxjs/Observable';

const purchaseEvent = Observable.fromEvent(
  new NativeEventEmitter(NativeModules.RNIapIos),
  'purchase-updated'
);
const purchaseSubscription = purchaseEvent.subscribe((transactionData) => {
  // Trigger server receipt validation here...
});
const errorEvent = Observable.fromEvent(
  new NativeEventEmitter(NativeModules.RNIapIos),
  'purchase-error'
);
const errorSubscription = errorEvent.subscribe((errorData) => {
  // Handle errors here...
});

initConnection() ๊ฐ€ README์˜ ์˜ˆ์ œ ์ฝ”๋“œ์— ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์˜ค๋ฅ˜๋ฅผ ๊ฒช๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค : # 1088,ํ•˜์ง€๋งŒ ๋ˆ„๊ตฐ๊ฐ€ ๋‚ด ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. (๋‚˜๋Š” ์—ฌ์ „ํžˆ ๋‚ด ์ฝ”๋“œ๊ฐ€ ์™„์ „ํžˆ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ํ™•์‹ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ...)

v5.1.1์—์„œ๋„์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. initConnection ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฆฌ์Šค๋„ˆ ์ฝœ๋ฐฑ์€ purchaseUpdate์—์„œ ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ๋Š” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ @mrozanski ์™€ ๊ฐ™์€ Observables๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

import React, { useContext, useEffect, useState } from 'react';
import { Alert, EmitterSubscription, Platform, NativeEventEmitter,
    NativeModules } from 'react-native';
import { connect } from 'react-redux';
import RNIap, {
    InAppPurchase,
    PurchaseError,
    SubscriptionPurchase,
    purchaseErrorListener,
    purchaseUpdatedListener,
} from 'react-native-iap';
import { Observable, Subscription } from 'rxjs';

const RNIAPEvent = new NativeEventEmitter(NativeModules.RNIapIos);
const purchaseObservable = new Observable((subscriber) => {
    RNIAPEvent.addListener('purchase-updated', (event) => {
        subscriber.next(event);
    })
})

const RNIAPErrorEvent = new NativeEventEmitter(NativeModules.RNIapIos);
const purchaseErrorObservable = new Observable((subscriber) => {
    RNIAPErrorEvent.addListener('purchase-error', (event) => {
        subscriber.next(event);
    })
})


const Wrapper = ({ ...props }) => {

    let purchaseUpdateSubscription: EmitterSubscription | Subscription | null = null;
    let purchaseErrorSubscription: EmitterSubscription | Subscription | null = null;

    const validateTransaction = async (purchase: SubscriptionPurchase) => {    
        return new Promise(async (resolve) => {
              //resolve(validationResponseFromYourBackend)
        }
    }

    const handleSubEvent = async (purchase: InAppPurchase | SubscriptionPurchase) => {
        const receipt = purchase.transactionReceipt;
        const purchaseToken = purchase.purchaseToken
        if (receipt) {
            try {
                const result = await validateTransaction(purchase);
                if (result.status === 200) {
                    RNIap.acknowledgePurchaseAndroid(purchaseToken).then(() => {
                        RNIap.finishTransaction(purchase, false)
                        .then(() => giveYourUserValue())
                        .catch((e) => {
                            //
                        })
                    })
                }
            } catch (err) {
                //
            }
        }
    }


    useEffect(() => {
        RNIap.initConnection()
            .then(() => {
                RNIap.flushFailedPurchasesCachedAsPendingAndroid().catch(() => {
                    // exception
                    })
                .then(() => {
                    if (Platform.OS === 'ios') {
                        //Documented implementation has issues purchaseUpdatedListener callback
                        purchaseUpdateSubscription = purchaseObservable.subscribe((purchase) => {
                            console.log('purchase observable', purchase)
                            handleSubEvent(purchase);
                        });

                        purchaseErrorSubscription = purchaseErrorObservable.subscribe((error) => {
                            console.log('purchaseErrorListener', error);
                        })

                    } else {
                        //for android use the documented method. Callbacks work.
                        purchaseUpdateSubscription = purchaseUpdatedListener(
                            (purchase: InAppPurchase | SubscriptionPurchase) => {
                                handleSubEvent(purchase);
                            }

                        );
                        purchaseErrorSubscription = purchaseErrorListener(
                            (error: PurchaseError) => {
                               console.log('purchaseErrorListener', error);
                            },
                        );
                    }

                })
            })
        return () => {
              // clear your listeners
             //eg if Subscription purchaseErrorSubscription.unsubscribe() 
            //eg if EmitterSubscription purchaseErrorSubscription.remove() 
        }
    }, []);

    return (
        <InAppSubContext.Provider
            value={{
                someValueYouWantPassedDown: 'theValue'
            }}
        >
            {props.children}
        </InAppSubContext.Provider>
    )
}

const mapState = (state) => ({ someProps: 'yeah' });

const InAppSubscriptionManager = connect(mapState)(Wrapper);

export default InAppSubscriptionManager;

์ด์ œ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ App.tsx ์•ฑ์„ ๋ž˜ํ•‘ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import InAppSubscriptionManager from './path/to/inAppSubscriptionManager';
const App = () => {

    return (
        <Provider store={store}>
                <InAppSubscriptionManager>

                    <AppNavigator />

                </InAppSubscriptionManager>
        </Provider>
    );
}

export default App;

๋„์›€์ด๋˜์–ด ๋‹คํ–‰์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” 6 ์›”๋ถ€ํ„ฐ ์ด๊ฒƒ์„ ์ƒ์‚ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์–ด๋Š ์‹œ์ ์—์„œ Observable์—์„œ ์ด๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค (์šฐ๋ฆฌ๋Š” typescript๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค)

      const purchaseEvent = new NativeEventEmitter(NativeModules.RNIapIos);
      const subscription = purchaseEvent.addListener(
        'purchase-updated',
        transactionData => {
          console.log('IAP-LOG purchase-updated');
          dispatch(validateRecepit(transactionData));
        }
      );
      const errorSubscription = purchaseEvent.addListener(
        'purchase-error',
        data => {
          crashlytics().log(`Purchase error ${JSON.stringify(data)}`);
          console.log('IAP-LOG purchase-error', data);
        }
      );
    };
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰