Commit e997483
fix: ensure FlutterResult and invokeMethod are always called on main thread (#98)
* fix: ensure FlutterResult and invokeMethod are always called on main thread
iOS 16 requires FlutterResult to be invoked on the main thread. When
OptimizelyClient.start() or decideAsync closures call result() from a
background thread under multi-SDK startup contention, iOS 16 silently
drops the response causing the Dart Future to never resolve or return
null, which previously crashed the app with an unhandled TypeError or
PlatformException.
Two layers fixed:
1. iOS native (SwiftOptimizelyFlutterSdkPlugin.swift)
- Added mainThreadResult() private helper that wraps FlutterResult
to always dispatch on the main thread (no-op if already on main)
- Applied once in handle() so every current and future method handler
is protected automatically — no per-handler changes needed
2. Dart layer (OptimizelyClientWrapper + OptimizelyUserContext)
- Added _invoke() helper that wraps every MethodChannel.invokeMethod
call with a null guard and PlatformException catch
- Null response returns {success:false} instead of crashing via
Map.from(null) → TypeError
- PlatformException is caught and returned as {success:false}
- All 18 call sites in OptimizelyClientWrapper and 14 in
OptimizelyUserContext now route through _invoke
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: update CLAUDE.md with expanded guidance and add IDE/env gitignore entries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: add unit tests for _invoke() null and PlatformException safety branches
Covers the two previously-uncovered error branches in the iOS 16 fix:
- Native returns null → success:false (no TypeError)
- Native throws PlatformException → success:false (no unhandled exception)
Tests both OptimizelyClientWrapper and OptimizelyUserContext.
Overall unit test coverage: 85.9% → 87.3%
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: ensure MethodChannel.Result is always called on main thread (Android)
Mirrors the iOS mainThreadResult() fix. Added safeResult() wrapper in
onMethodCall() that dispatches success/error/notImplemented to the Android
main thread via Handler(Looper.getMainLooper()) when called from a
background thread. Applied once so all current and future handlers are
automatically protected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: use nullable-safe TestDefaultBinaryMessengerBinding access in tests
Flutter 3.0.5 (used in CI) exposes instance as nullable — use ?.
pattern consistent with existing test suite to fix compilation failure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent 89bbc6d commit e997483
7 files changed
Lines changed: 600 additions & 195 deletions
File tree
- android/src/main/java/com/optimizely/optimizely_flutter_sdk
- ios/Classes
- lib/src
- user_context
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | 11 | | |
22 | 12 | | |
23 | 13 | | |
24 | 14 | | |
25 | 15 | | |
| 16 | + | |
26 | 17 | | |
27 | 18 | | |
28 | | - | |
29 | | - | |
30 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
31 | 22 | | |
32 | 23 | | |
33 | 24 | | |
34 | 25 | | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
| 26 | + | |
39 | 27 | | |
40 | 28 | | |
41 | 29 | | |
| |||
47 | 35 | | |
48 | 36 | | |
49 | 37 | | |
50 | | - | |
| 38 | + | |
51 | 39 | | |
52 | | - | |
| 40 | + | |
53 | 41 | | |
54 | 42 | | |
55 | 43 | | |
| |||
58 | 46 | | |
59 | 47 | | |
60 | 48 | | |
61 | | - | |
| 49 | + | |
62 | 50 | | |
63 | 51 | | |
64 | 52 | | |
65 | 53 | | |
66 | 54 | | |
67 | | - | |
| 55 | + | |
68 | 56 | | |
69 | 57 | | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
| 58 | + | |
| 59 | + | |
88 | 60 | | |
89 | | - | |
90 | | - | |
91 | | - | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
92 | 64 | | |
93 | 65 | | |
94 | 66 | | |
95 | 67 | | |
96 | | - | |
| 68 | + | |
97 | 69 | | |
98 | 70 | | |
99 | | - | |
100 | | - | |
101 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
102 | 101 | | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
103 | 133 | | |
104 | | - | |
| 134 | + | |
105 | 135 | | |
106 | | - | |
107 | | - | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
108 | 149 | | |
109 | 150 | | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
| 151 | + | |
| 152 | + | |
114 | 153 | | |
| 154 | + | |
115 | 155 | | |
116 | 156 | | |
117 | | - | |
118 | | - | |
119 | | - | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
120 | 162 | | |
121 | 163 | | |
122 | 164 | | |
123 | | - | |
124 | | - | |
125 | | - | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
0 commit comments