stleamist / BetterSafariView

A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.
MIT License
581 stars 57 forks source link

Fix: non-main thread issue when closing WebAuthenticationSession #44

Open zooxop opened 1 year ago

zooxop commented 1 year ago

Hello ๐Ÿ‘‹

I found a problem when using WebAuthenticationSession in a project that uses TCA framework

Problem:

A non-main thread issue occurs when closing the WebAuthenticationSession window.

(Warnings generated by the TCA library)

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-06 แ„‹แ…ฉแ„’แ…ฎ 3 10 37

(Warnings generated by the SwiftUI Framework)

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-06 แ„‹แ…ฉแ„’แ…ฎ 3 11 07

Cause:

The problem does not occur when using the pure SwiftUI @Binding. However, when assigning a Binding variable to isPresented: using TCA, it appears that the action of the Binding variable becoming false when the window closes is executed in the background. (This is just a guess of mine, so it may be wrong.)

Anyway, the problem occurs when the value of the variable item is changeed to nil inside the completionHandler of the WebAuthenticationPresenter.

Solution:

This commit is modified to run on the main thread in the resetItemBinding() function.

private func resetItemBinding() {
-    parent.item = nil
+    DispatchQueue.main.async {
+        self.parent.item = nil
+    }
}

Testing:

I confirmed that this modification does not cause side effects when using pure SwiftUI.

Request:

Please let me know if there is a possibility that another problem may occur due to this modification. If not, please reflect it in the main branch.

Thank you for your time. Have a nice day.




์•ˆ๋…•ํ•˜์„ธ์š”. ์˜์–ด๋กœ ๋ฒˆ์—ญํ•˜๋Š” ๊ณผ์ •์—์„œ ์˜๋„๊ฐ€ ์ •ํ™•ํžˆ ์ „๋‹ฌ๋˜์ง€ ์•Š์€ ๋ถ€๋ถ„์ด ์žˆ์„ ๊ฒƒ ๊ฐ™์•„, ํ•œ๊ตญ์–ด๋กœ ์š”์•ฝํ•œ ๋‚ด์šฉ๋„ ํ•จ๊ป˜ ๊ธฐ์žฌํ•ฉ๋‹ˆ๋‹ค.

TCA๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ WebAuthenticationSession์„ ์‚ฌ์šฉํ•  ๋•Œ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ :

WebAuthenticationSession ์ฐฝ์ด ๋‹ซํž ๋•Œ, non-main thread ๊ด€๋ จ ๋ฌธ์ œ ๋ฐœ์ƒ. (์ด๋ฏธ์ง€ ์ƒ๋žต)

์›์ธ ํŒŒ์•… :

์ˆœ์ˆ˜ํ•œ SwiftUI์˜ @Binding์„ ์ด์šฉํ•˜์˜€์„ ๋•Œ๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ TCA๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ isPresented:์— Binding ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๊ฒŒ ๋˜๋ฉด ์ฐฝ์ด ๋‹ซํžˆ๋ฉด์„œ Binding ๋ณ€์ˆ˜๊ฐ€ false๋กœ ๋ณ€ํ•˜๋Š” ๋™์ž‘์ด background์—์„œ ์‹คํ–‰์ด ๋˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. (์ถ”์ธก์ด๋ฏ€๋กœ, ํ‹€๋ ธ์„ ์ˆ˜๋„ ์žˆ์Œ.)

์–ด์จŒ๋“ , ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์‹œ์ ์€ WebAuthenticationPresenter์˜ completionHandler์˜ ๋™์ž‘ ๋‚ด๋ถ€์—์„œ ๋ณ€์ˆ˜ item์˜ ๊ฐ’์„ nil๋กœ ์ดˆ๊ธฐํ™” ํ•  ๋•Œ์ธ ๊ฒƒ์œผ๋กœ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ์•ˆ ์ œ์‹œ :

resetItemBinding() ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋ฅผ main thread์—์„œ ๋™์ž‘ํ•˜๋„๋ก ์ˆ˜์ •.


์ด ์ˆ˜์ •์€ ์ˆœ์ˆ˜ํ•˜๊ฒŒ SwiftUI๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด side effect๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๋Š”๊ฒƒ์œผ๋กœ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด ์ˆ˜์ •์œผ๋กœ ์ธํ•ด ์ œ๊ฐ€ ๋ชจ๋ฅด๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์‹œ๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด main branch์— ๋ฐ˜์˜์‹œ์ผœ์ฃผ์‹œ๊ธฐ๋ฅผ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๊ณ ๋ง™์Šต๋‹ˆ๋‹ค. ์ข‹์€ ํ•˜๋ฃจ ๋ณด๋‚ด์„ธ์š”.