<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Muhammad haris baig</title>
    <description>The latest articles on DEV Community by Muhammad haris baig (@muhammad_harisbaig_1268d).</description>
    <link>https://dev.to/muhammad_harisbaig_1268d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1885181%2F7cf1ce11-1206-4f0d-b2a2-0c1873349367.jpg</url>
      <title>DEV Community: Muhammad haris baig</title>
      <link>https://dev.to/muhammad_harisbaig_1268d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/muhammad_harisbaig_1268d"/>
    <language>en</language>
    <item>
      <title>React Native + Android 16: The SDK Upgrade That Looks Easy Until Your UI Breaks</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Tue, 28 Jul 2026 20:38:43 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/react-native-android-16-the-sdk-upgrade-that-looks-easy-until-your-ui-breaks-520e</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/react-native-android-16-the-sdk-upgrade-that-looks-easy-until-your-ui-breaks-520e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Moving from target SDK 35 to 36 looks like a simple Gradle change. In a real React Native app, the build may be the easiest part.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your React Native Android app is still targeting API 35, Android 16 (API 36) should be on your migration roadmap.&lt;/p&gt;

&lt;p&gt;Google Play requires apps to target Android 16 (API 36) for updates starting August 31, 2026.&lt;/p&gt;

&lt;p&gt;The configuration changes are relatively straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;compileSdkVersion&lt;/code&gt;: 35 → 36&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;targetSdkVersion&lt;/code&gt;: 35 → 36&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;buildToolsVersion&lt;/code&gt;: 35.x → 36.x&lt;/li&gt;
&lt;li&gt;Android Gradle Plugin: 8.7.x → 8.9.1+&lt;/li&gt;
&lt;li&gt;Gradle: 8.9 → 8.11.1+&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;minSdkVersion&lt;/code&gt;: remained 24&lt;/li&gt;
&lt;li&gt;No React Native major version upgrade was required just for this SDK bump&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first build succeeded.&lt;/p&gt;

&lt;p&gt;Then the real work started.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Easy" SDK Upgrade
&lt;/h2&gt;

&lt;p&gt;The first mistake teams can make is assuming:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The app builds, so the migration is done."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not quite.&lt;/p&gt;

&lt;p&gt;An Android SDK upgrade can change platform behavior without changing a single line of your React Native JavaScript.&lt;/p&gt;

&lt;p&gt;You may suddenly find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headers moving under the status bar&lt;/li&gt;
&lt;li&gt;Notches overlapping content&lt;/li&gt;
&lt;li&gt;Back buttons becoming difficult to tap&lt;/li&gt;
&lt;li&gt;Keyboard behavior changing&lt;/li&gt;
&lt;li&gt;Forms behaving differently&lt;/li&gt;
&lt;li&gt;Existing navigation issues surfacing during testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why I see target SDK migrations as &lt;strong&gt;behavioral migrations&lt;/strong&gt;, not just build configuration changes.&lt;/p&gt;

&lt;p&gt;Our approach was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Get the app compliant with the new target SDK with the smallest possible change set.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We didn't combine the migration with a React Native upgrade, navigation rewrite, UI redesign, or complete safe-area refactor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First make the platform migration. Then fix the platform-specific behavior it exposes.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Breakage: Edge-to-Edge
&lt;/h2&gt;

&lt;p&gt;The biggest issue we encountered was Android's edge-to-edge behavior.&lt;/p&gt;

&lt;p&gt;With Android 16, edge-to-edge is enforced, and &lt;code&gt;windowOptOutEdgeToEdgeEnforcement&lt;/code&gt; is no longer a reliable solution.&lt;/p&gt;

&lt;p&gt;This changes an assumption many React Native apps have quietly depended on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The operating system will leave space for my content below the status bar."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With edge-to-edge, your application can draw behind system bars.&lt;/p&gt;

&lt;p&gt;That's fine when the UI is intentionally designed for it.&lt;/p&gt;

&lt;p&gt;It's a problem when your existing UI assumes the system will automatically keep content away from the status bar.&lt;/p&gt;

&lt;p&gt;Our first symptoms were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headers partially hidden&lt;/li&gt;
&lt;li&gt;Content underneath the notch&lt;/li&gt;
&lt;li&gt;Back buttons becoming harder to tap&lt;/li&gt;
&lt;li&gt;Authentication screens looking incorrect&lt;/li&gt;
&lt;li&gt;Attempted fixes creating excessive spacing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, the migration became more than an SDK upgrade.&lt;/p&gt;

&lt;p&gt;It became a UI architecture problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Don't Fix Safe Areas Screen by Screen
&lt;/h2&gt;

&lt;p&gt;The obvious solution is to add safe-area padding to every screen.&lt;/p&gt;

&lt;p&gt;Be careful.&lt;/p&gt;

&lt;p&gt;If your navigation container already handles the top inset and individual screens add their own safe-area padding, you can end up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Double padding&lt;/li&gt;
&lt;li&gt;Large empty spaces&lt;/li&gt;
&lt;li&gt;Misaligned headers&lt;/li&gt;
&lt;li&gt;Inconsistent spacing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The approach that worked better for our architecture was to apply the Android top inset &lt;strong&gt;once at the root router/navigation layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of every screen asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Do I need to add status bar padding?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We established a single responsibility:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The root navigation layer owns the Android top inset.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The principle is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Insets should have one clear owner.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This makes the layout hierarchy easier to reason about and avoids solving the same platform problem repeatedly across individual screens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Status Bar Color Is Part of the UI
&lt;/h2&gt;

&lt;p&gt;Another issue appeared on authentication screens.&lt;/p&gt;

&lt;p&gt;A fixed white status-bar filler looked fine on white screens.&lt;/p&gt;

&lt;p&gt;Then we opened a colored authentication screen.&lt;/p&gt;

&lt;p&gt;Suddenly, there was a white strip at the top.&lt;/p&gt;

&lt;p&gt;The overlap was fixed.&lt;/p&gt;

&lt;p&gt;The UI was still wrong.&lt;/p&gt;

&lt;p&gt;The lesson is that system-bar handling isn't only about spacing. It's also about &lt;strong&gt;visual context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When handling edge-to-edge, think about two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Where should the content start?&lt;/li&gt;
&lt;li&gt;What should appear behind the system bar?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An authentication screen may need a branded background, while the main application may use white.&lt;/p&gt;

&lt;p&gt;A hardcoded white filler isn't a universal solution. Simply making everything transparent isn't necessarily the answer either.&lt;/p&gt;

&lt;p&gt;This is another reason centralized root-level handling is easier to maintain than manually adding spacers across dozens of screens.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Keyboard Problem: &lt;code&gt;adjustResize&lt;/code&gt; Isn't Enough
&lt;/h2&gt;

&lt;p&gt;The second major issue was keyboard behavior.&lt;/p&gt;

&lt;p&gt;We had screens using the familiar combination of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;KeyboardAvoidingView&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;behavior="padding"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;windowSoftInputMode="adjustResize"&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Historically, this pattern has worked well for many React Native applications.&lt;/p&gt;

&lt;p&gt;But edge-to-edge changes what you can expect from classic window resizing.&lt;/p&gt;

&lt;p&gt;On Android 15+ / API 35+, and continuing into Android 16, relying solely on &lt;code&gt;adjustResize&lt;/code&gt; is no longer sufficient in edge-to-edge scenarios.&lt;/p&gt;

&lt;p&gt;The result can look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User taps an input
        ↓
Keyboard opens
        ↓
Window doesn't resize as expected
        ↓
Content remains behind the keyboard
        ↓
KeyboardAvoidingView can't fully solve it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't necessarily a React Native bug.&lt;/p&gt;

&lt;p&gt;It's a change in how Android handles the application's window and system insets.&lt;/p&gt;

&lt;p&gt;The solution we used was to handle the IME (keyboard) inset natively in &lt;code&gt;MainActivity&lt;/code&gt; for SDK 35+:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect the keyboard using &lt;code&gt;WindowInsets&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Read the bottom IME inset&lt;/li&gt;
&lt;li&gt;Apply the required bottom padding to the root content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Keyboard opens
      ↓
Android reports IME WindowInset
      ↓
MainActivity receives the bottom inset
      ↓
Root content gets bottom padding
      ↓
React Native UI moves above the keyboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is more reliable than trying to solve every form with increasingly complex &lt;code&gt;ScrollView&lt;/code&gt; or &lt;code&gt;KeyboardAvoidingView&lt;/code&gt; styles.&lt;/p&gt;

&lt;p&gt;One recommendation from this migration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't randomly change your layouts because the keyboard is covering content.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We tried layout-level approaches that technically moved the content but also disturbed centering and spacing.&lt;/p&gt;

&lt;p&gt;If the UI was correct before the platform change, fix the platform behavior at the platform layer whenever possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Test After API 35 → 36
&lt;/h2&gt;

&lt;p&gt;Don't stop after confirming that the app builds and installs.&lt;/p&gt;

&lt;p&gt;Run a focused regression test.&lt;/p&gt;

&lt;h3&gt;
  
  
  System UI
&lt;/h3&gt;

&lt;p&gt;Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status bar and notch behavior&lt;/li&gt;
&lt;li&gt;Edge-to-edge&lt;/li&gt;
&lt;li&gt;Navigation bar&lt;/li&gt;
&lt;li&gt;Back gesture&lt;/li&gt;
&lt;li&gt;Header alignment&lt;/li&gt;
&lt;li&gt;Touch targets near system bars&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Keyboard
&lt;/h3&gt;

&lt;p&gt;Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login and authentication forms&lt;/li&gt;
&lt;li&gt;Long forms&lt;/li&gt;
&lt;li&gt;Multiple text inputs&lt;/li&gt;
&lt;li&gt;Password fields&lt;/li&gt;
&lt;li&gt;Keyboard opening and closing&lt;/li&gt;
&lt;li&gt;Content near the bottom of the screen&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Core Android Features
&lt;/h3&gt;

&lt;p&gt;Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push notifications&lt;/li&gt;
&lt;li&gt;Deep links&lt;/li&gt;
&lt;li&gt;Camera&lt;/li&gt;
&lt;li&gt;Gallery&lt;/li&gt;
&lt;li&gt;File selection&lt;/li&gt;
&lt;li&gt;Permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Navigation
&lt;/h3&gt;

&lt;p&gt;Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nested navigators&lt;/li&gt;
&lt;li&gt;Tab and stack navigation&lt;/li&gt;
&lt;li&gt;Back button and gesture&lt;/li&gt;
&lt;li&gt;Deep links into nested screens&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Devices
&lt;/h3&gt;

&lt;p&gt;At minimum, test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android 16 / API 36&lt;/li&gt;
&lt;li&gt;One older supported Android version&lt;/li&gt;
&lt;li&gt;A device with a notch or cutout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And run a quick iOS sanity check.&lt;/p&gt;

&lt;p&gt;React Native shares JavaScript layout code across platforms, so Android-specific changes should not accidentally affect iOS.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Biggest Lesson
&lt;/h2&gt;

&lt;p&gt;Android SDK upgrades are becoming less about changing a number in Gradle and more about understanding how Android is evolving.&lt;/p&gt;

&lt;p&gt;The API 36 migration is a good example.&lt;/p&gt;

&lt;p&gt;The configuration change is relatively small.&lt;/p&gt;

&lt;p&gt;The behavioral impact can be much larger.&lt;/p&gt;

&lt;p&gt;The most important lesson from our migration was to avoid over-engineering the solution.&lt;/p&gt;

&lt;p&gt;We didn't need to redesign the entire application.&lt;/p&gt;

&lt;p&gt;We needed to identify where Android 16 changed existing assumptions and fix those assumptions at the correct layer.&lt;/p&gt;

&lt;p&gt;For us, that meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Centralizing Android top inset handling at the root router&lt;/li&gt;
&lt;li&gt;Avoiding duplicate safe-area padding&lt;/li&gt;
&lt;li&gt;Matching system-bar backgrounds to the screen context&lt;/li&gt;
&lt;li&gt;Handling keyboard IME insets natively for newer Android versions&lt;/li&gt;
&lt;li&gt;Keeping the iOS safe-area path unchanged&lt;/li&gt;
&lt;li&gt;Avoiding layout hacks that introduced new spacing problems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal wasn't to rewrite the app.&lt;/p&gt;

&lt;p&gt;The goal was to make the &lt;strong&gt;smallest architectural changes necessary&lt;/strong&gt; to keep the app stable on the new platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Target SDK upgrades are behavioral migrations.&lt;/strong&gt;&lt;br&gt;
A successful build doesn't mean your migration is complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Android 16 edge-to-edge needs intentional UI handling.&lt;/strong&gt;&lt;br&gt;
Don't assume the system will keep your content away from system bars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Give insets one clear owner.&lt;/strong&gt;&lt;br&gt;
Centralized handling is usually safer than adding safe-area fixes to every screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Keyboard behavior needs platform-aware handling.&lt;/strong&gt;&lt;br&gt;
With edge-to-edge, don't rely blindly on &lt;code&gt;adjustResize&lt;/code&gt; and &lt;code&gt;KeyboardAvoidingView&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Keep the migration surgical.&lt;/strong&gt;&lt;br&gt;
Get Play compliance done first, then fix UI and runtime issues one by one.&lt;/p&gt;

&lt;p&gt;Android 16 won't be the last platform change React Native developers have to deal with.&lt;/p&gt;

&lt;p&gt;The engineers who handle these migrations well won't be the ones who simply know which Gradle value to change.&lt;/p&gt;

&lt;p&gt;They'll be the ones who understand &lt;strong&gt;where JavaScript ends, where React Native begins, and where Android platform behavior takes over.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the real skill behind maintaining production-grade React Native applications.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>google</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Upgrading React-Native from Android SDK 34 35: Real Issues, Real Fixes, and What No One Tells You</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Tue, 18 Nov 2025 18:36:21 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/upgrading-react-native-from-android-sdk-34-35-real-issues-real-fixes-and-what-no-one-tells-you-5p9</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/upgrading-react-native-from-android-sdk-34-35-real-issues-real-fixes-and-what-no-one-tells-you-5p9</guid>
      <description>&lt;p&gt;Upgrading your React-Native app from Android SDK 34 to 35 should be simple. Google releases a new SDK → you update compileSdkVersion and targetSdkVersion → rebuild → ship update. Right?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrong&lt;/strong&gt;.&lt;br&gt;
The Android 35 upgrade is one of the most painful upgrades the community has faced since Android 28 → 29.&lt;br&gt;
This article documents every issue I personally faced, how I fixed them, what other developers are reporting globally, and the ultimate fix almost no one talks about.&lt;br&gt;
If you are upgrading your RN project to Android 35 - this guide will save you hours (or days) of debugging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgktzgdat0wt7pama3w6q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgktzgdat0wt7pama3w6q.gif" alt=" " width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I&amp;nbsp;Upgraded&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;compileSdkVersion = 34 -&amp;gt; // upgrade to 35&lt;br&gt;
targetSdkVersion = 35 -&amp;gt; // upgrade to 35&lt;br&gt;
buildToolsVersion = "34.0.0" -&amp;gt; // upgrade to 35.0.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I also added this to styles.xml (required for Android 15 / API 35 edge-to-edge changes):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;item name="android:windowOptOutEdgeToEdgeEnforcement"&amp;gt;true&amp;lt;/item&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;My project is on:&lt;/strong&gt;&lt;br&gt;
React-Native 0.72.7&lt;br&gt;
70+ libraries (Zego, Firebase, Notifee, Maps, FS, Vimeo, RN Config, etc.)&lt;br&gt;
Kotlin code + Java code (important later)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Nightmare Begins - AAPT2 Crash on Android&amp;nbsp;35&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zpw6w1wb3m8jk6yk7ui.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zpw6w1wb3m8jk6yk7ui.gif" alt=" " width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As soon as I attempted to build:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Execution failed for task :app:processProdDebugResources&lt;br&gt;
Android resource linking failed&lt;br&gt;
RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data&lt;br&gt;
Failed to load resources table in android-35/android.jar&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a fatal AAPT2 crash that makes the entire build impossible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I tried following:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✔ Deleted Android 35&amp;nbsp;platform&lt;br&gt;
&lt;code&gt;rm -rf ~/Library/Android/sdk/platforms/android-35&lt;/code&gt;&lt;br&gt;
✔ Reinstalled using SDK Manager&lt;br&gt;
&amp;nbsp;✔ Invalidated caches&lt;br&gt;
&amp;nbsp;✔ Removed&amp;nbsp;.gradle, build, intermediates&lt;br&gt;
&amp;nbsp;✔ Clean build / rebuild&lt;br&gt;
&amp;nbsp;✔ Reinstalled Android Studio&lt;br&gt;
&amp;nbsp;✔ Tried with Staging / Prod flavors&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing worked.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because Android 35 ships a new resources table format, but AGP (Android Gradle Plugin) still ships an older AAPT2 binary that can't read it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is why the error mentions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data&lt;br&gt;
The Fix Almost Nobody&amp;nbsp;Knows&lt;br&gt;
The build worked instantly when I added this to gradle.properties:&lt;br&gt;
android.aapt2Version=8.6.1-11315950&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✔ Why it works (short&amp;nbsp;version)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Android 35 requires a newer AAPT2, not the old one bundled with AGP 7.x.&lt;br&gt;
Setting this line downloads a fresh AAPT2 build:&lt;br&gt;
8.6.1-11315950&lt;br&gt;
…which can parse Android 35's updated android.jar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BAM - build succeeds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1uddwye1450u8iwgs23l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1uddwye1450u8iwgs23l.gif" alt=" " width="500" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✔ Why Google doesn't document&amp;nbsp;it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because the official "fix" is to upgrade AGP to 8.x - but RN 0.72 cannot yet use AGP 8 safely.&lt;br&gt;
So this property is an internal escape hatch that allows RN developers to upgrade without rewriting their entire Android build configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Next Problem: NoSuchMethodError reversed()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After the build succeeded, the app crashed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;java.lang.NoSuchMethodError: No virtual method reversed()Ljava/util/List;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This happened because:&lt;/strong&gt;&lt;br&gt;
JDK 17+ ships List.reversed()&lt;br&gt;
But many RN/Kotlin libraries compile against older Kotlin stdlib&lt;br&gt;
When mixed, Dalvik cannot locate the JDK method → runtime crash&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✔ How I fixed&amp;nbsp;it&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;I replaced all occurrences of reversed() with:&lt;br&gt;
asReversed()&lt;br&gt;
This exists in older Kotlin stdlib and works everywhere.&lt;br&gt;
I patched my own Kotlin code AND created patches for:&lt;br&gt;
react-native-screens&lt;br&gt;
react-native-gesture-handler&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Because these libs internally used reversed() as well.&lt;br&gt;
I applied the patches using patch-package.&lt;br&gt;
&lt;strong&gt;Expect MORE Errors While Upgrading - Common Issues (Community Reports)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developers upgrading to 35 commonly see:&lt;br&gt;
🔻 &lt;strong&gt;AAPT2 resource linking&amp;nbsp;crash&lt;/strong&gt;&lt;br&gt;
🔻 &lt;strong&gt;"Execution failed for task&amp;nbsp;:app:mergeDebugResources"&lt;br&gt;
Caused by broken vector drawables under new validator.&lt;/strong&gt;&lt;br&gt;
🔻 &lt;strong&gt;Edge-to-edge mandatory updates&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;styles.xml must contain:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;item name="android:windowOptOutEdgeToEdgeEnforcement"&amp;gt;true&amp;lt;/item&amp;gt;&lt;/code&gt;&lt;br&gt;
🔻 &lt;strong&gt;Kotlin / Java binary incompatibilities&lt;/strong&gt;&lt;br&gt;
reversed(), JDK 17 methods missing, etc.&lt;br&gt;
🔻 &lt;strong&gt;Build tools&amp;nbsp;mismatch&lt;/strong&gt;&lt;br&gt;
Build-tools 35.0.0 is still in preview so many users end up with partial installs.&lt;br&gt;
🔻 &lt;strong&gt;Firebase / Notifee / React-Native-Maps needing updated&lt;/strong&gt; peer&amp;nbsp;versions&lt;br&gt;
Especially with 35's new system location permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠 6. Full Checklist for Upgrading React-Native from API 34 →&amp;nbsp;35&lt;/strong&gt;&lt;br&gt;
1️⃣ &lt;strong&gt;Update build configuration&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;android/build.gradle:&lt;br&gt;
compileSdkVersion 35&lt;br&gt;
targetSdkVersion 35&lt;/code&gt;&lt;br&gt;
2️⃣ &lt;strong&gt;Add required edge-to-edge rules&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;res/values/styles.xml:&lt;br&gt;
&amp;lt;item name="android:windowOptOutEdgeToEdgeEnforcement"&amp;gt;true&amp;lt;/item&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;3️⃣ Fix AAPT2&amp;nbsp;crash&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;gradle.properties:&lt;br&gt;
android.aapt2Version=8.6.1-11315950&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;4️⃣ Upgrade Android Build&amp;nbsp;Tools&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;SDK Manager → Install:&lt;br&gt;
Android SDK Platform 35&lt;br&gt;
Build Tools 35.x.x&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5️⃣ Fix Kotlin/JDK reversed() crash&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Search project:&lt;br&gt;
reversed()&lt;br&gt;
Replace with:&lt;br&gt;
asReversed()&lt;br&gt;
Apply patches for:&lt;br&gt;
RN Screens&lt;br&gt;
Gesture Handler&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6️⃣ Rebuild&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd android&lt;br&gt;
./gradlew clean&lt;br&gt;
./gradlew assembleDebug&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🏁 7. Final&amp;nbsp;Result&lt;/strong&gt;&lt;br&gt;
After applying:&lt;br&gt;
✔ AAPT2 upgrade&lt;br&gt;
&amp;nbsp;✔ Edge-to-edge opt-out&lt;br&gt;
&amp;nbsp;✔ Kotlin reversed() fix&lt;br&gt;
&amp;nbsp;✔ Library patches&lt;br&gt;
The project builds and runs on:&lt;br&gt;
Android 15 emulator, Api 29 till api 35 builds fine&lt;br&gt;
Physical Pixel device&lt;br&gt;
Both debug and release&lt;br&gt;
All staging / prod flavors&lt;/p&gt;

&lt;p&gt;Zero crashes, zero resource failures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm09g4h62ijlrutjq6bxt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm09g4h62ijlrutjq6bxt.gif" alt=" " width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>reactnative</category>
      <category>sdk35</category>
      <category>upgrade</category>
    </item>
    <item>
      <title>🚨 The “10x Developer” Myth in the AI Era 🚨</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Mon, 03 Nov 2025 19:16:36 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/the-10x-developer-myth-in-the-ai-era-170d</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/the-10x-developer-myth-in-the-ai-era-170d</guid>
      <description>&lt;p&gt;Everyone’s chasing the “10x developer” dream right now.&lt;br&gt;
Companies want to cut costs, hire fewer devs, and believe AI can multiply output. On paper, it sounds smart — one developer doing the work of five. But here’s the truth no one likes to talk about 👇&lt;/p&gt;

&lt;p&gt;Yes, AI can help. It can speed up delivery. It can autocomplete code.&lt;br&gt;
But it &lt;strong&gt;can’t care&lt;/strong&gt; about your codebase. It doesn’t understand &lt;em&gt;why&lt;/em&gt; clean, scalable, maintainable code matters in the long run.&lt;/p&gt;

&lt;p&gt;Right now, developers are being pushed to hit impossible deadlines — tasks that took 3–4 days in the pre-AI era are now “expected” in a single day. Businesses only look at the end result, not the foundation. The problem?&lt;br&gt;
When that foundation cracks, no AI can fix it.&lt;/p&gt;

&lt;p&gt;Sooner or later, you’ll have to rebuild or refactor from scratch.&lt;br&gt;
And that’s when reality hits — &lt;em&gt;you can’t ship quality at speed forever&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It’s not about choosing between quality and quantity. It’s about &lt;strong&gt;balance&lt;/strong&gt;.&lt;br&gt;
Developers need to stand up and communicate that code quality &lt;em&gt;is&lt;/em&gt; business value. A strong codebase is what keeps your product alive, scalable, and future-proof.&lt;/p&gt;

&lt;p&gt;So yes — use AI. Use it to learn, build, and grow faster.&lt;br&gt;
But never stop writing code that you’re proud of.&lt;br&gt;
Because shortcuts always catch up.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>10xdeveloper</category>
      <category>techtruths</category>
      <category>devbugsmash</category>
    </item>
    <item>
      <title>Build Voice Messaging in React Native with Reusable Gists</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Mon, 16 Jun 2025 11:38:37 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/build-voice-messaging-in-react-native-with-reusable-gists-2e2g</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/build-voice-messaging-in-react-native-with-reusable-gists-2e2g</guid>
      <description>&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Voice messaging is now a staple in chat experiences. Users expect to record, send, and play audio with ease — and developers deserve tools that don't fight back. That’s why I broke down a fully functional voice messaging system into simple, focused gists that you can plug into any React Native project.&lt;/p&gt;

&lt;p&gt;No full-blown package. No bloated dependencies. Just modular code that works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔧 What the Feature Does&lt;/strong&gt;&lt;br&gt;
This voice message system includes:&lt;/p&gt;

&lt;p&gt;Tap-to-record with visual timer&lt;br&gt;
Cancel or send recording&lt;br&gt;
Upload logic using your own backend (ZEGOCLOUD in my case)&lt;br&gt;
Full-featured playback&lt;br&gt;
Play/pause&lt;br&gt;
Seek&lt;br&gt;
Speed toggle (1x, 1.5x, 2x)&lt;br&gt;
Auto-stop/reset&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 Gist-Based Breakdown&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MicButton.js
A recording button with timer display. Users can cancel, send, or re-record. Handles UI state + timer logic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Starts recording on press-in&lt;br&gt;
Tracks elapsed time&lt;br&gt;
Sends file or cancels on tap&lt;br&gt;
Reusable as a controlled component with props for recorder logic&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/harisbaig100/dee54c12be80d83092b1e03085218943" rel="noopener noreferrer"&gt;Gits Link for MicButton&lt;/a&gt; 🔗&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xg6u7vdzpwaidrbbwa8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xg6u7vdzpwaidrbbwa8.gif" alt="Image description" width="686" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;VoiceMessagePlayer.js
An audio player with scrubber, speed control, and clean UI. Manages playback for local or remote audio files.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fetches file path&lt;br&gt;
Handles permission (Android/iOS)&lt;br&gt;
Manages current playing state globally&lt;br&gt;
Speeds: 1x, 1.5x, 2x&lt;br&gt;
Seeks to any point in the track&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/harisbaig100/859c09d8ad609f09496a9e5def63c6e9" rel="noopener noreferrer"&gt;Gist Link for VoiceMessagePlayer 🔗&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7rhuydmstt30yicq4jm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7rhuydmstt30yicq4jm.gif" alt="Image description" width="688" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Recorder Functions
Async functions to:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start recording (with platform-specific formats)&lt;br&gt;
Stop recording and send it to your backend&lt;br&gt;
Cancel and clean up listeners&lt;/p&gt;

&lt;p&gt;Integrate these into your parent component and pass to MicButton.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/harisbaig100/53979050673202ed89bbeaed7aef1cf1" rel="noopener noreferrer"&gt;Gist Link For Recorder Functions 🔗&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;sendVoiceMessage() — Gist Link
Customizable logic to send the audio message over any provider (ZEGOCLOUD in this case).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Strips file:// prefix&lt;br&gt;
Formats duration, file name, type&lt;br&gt;
Builds a push config and sends the message&lt;/p&gt;

&lt;p&gt;Example Workflow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;MicButton 
  startRecording={startRecording} 
  onStopRecord={onStopRecord} 
  recorderInstance={audioRecorderPlayer} 
/&amp;gt;

{message.type === 13 &amp;amp;&amp;amp; (
  &amp;lt;VoiceMessagePlayer item={message} isSender={true} /&amp;gt;
)}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you drop recording and playback directly into any chat UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Gists, Not a Package?&lt;/strong&gt;&lt;br&gt;
🛠️ Devs can tweak each part without digging into node_modules&lt;br&gt;
⚡ Faster adoption&lt;br&gt;
📦 Packages are overkill when you just need a few focused files&lt;/p&gt;

&lt;p&gt;If you’re building chat, customer support, or community apps — this will save you days. Take the gists, plug them in, and ship voice features users love.&lt;/p&gt;

&lt;p&gt;Built for developers. Shared with developers.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>reactnative</category>
      <category>react</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Fixing Common Issues in Zego Call Kit for React Native Developers 💻🚀</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Mon, 10 Feb 2025 20:12:44 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/fixing-common-issues-in-zego-call-kit-for-react-native-developers-2kj3</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/fixing-common-issues-in-zego-call-kit-for-react-native-developers-2kj3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction 🛠️&lt;/strong&gt;&lt;br&gt;
If you're a React Native developer working with Zego Call Kit, you've likely encountered frustrating issues with no straightforward solutions available online. I faced two major problems while integrating @zegocloud/zego-uikit-prebuilt-call-rn and zego-callkit-react-native, and after much debugging, I found effective fixes that will save you a lot of time.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk you through these issues, their causes, and the solutions I implemented to resolve them using a patching technique. Hopefully, this will save you time and effort! ⏳&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue #1: ZegoUIKit.kitLogInfo error apply of undefined ⚠️&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Problem ❌&lt;/strong&gt;&lt;br&gt;
This issue originated from the @zegocloud/zego-uikit-prebuilt-call-rn library. When running my Android app, it would crash due to an undefined method kitLogInfo, while on iOS, it would just show a warning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&amp;nbsp;🧐&lt;/strong&gt;&lt;br&gt;
The kitLogInfo function was expected to be present in ZegoUIKitLogger, but it was missing in some versions of the library, leading to runtime errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution ✅&lt;/strong&gt;&lt;br&gt;
I resolved this by modifying the logging mechanism using a patch. The original problematic code looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {ZegoUIKitLogger} from '@zegocloud/zego-uikit-rn';
const module = 'PrebuiltCall'
export const zloginfo = (...msg) =&amp;gt; {
  ZegoUIKitLogger.logInfo(module, ...msg);
};
export const zlogwarning = (...msg) =&amp;gt; {
  ZegoUIKitLogger.logWarning(module, ...msg);
};
export const zlogerror = (...msg) =&amp;gt; {
  ZegoUIKitLogger.logError(module, ...msg);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;I changed it to:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
"use strict";
import { Platform } from "react-native";
import _zegoUikitRn from "@zegocloud/zego-uikit-rn";
const zloginfo = (...msg) =&amp;gt; {
  if (_zegoUikitRn.default.kitLogInfo) {
    _zegoUikitRn.default.kitLogInfo('PrebuiltCall', ...msg);
  } else {
    console.warn(`kitLogInfo is not defined in ZegoUIKit in ${Platform.OS}`);
  }
};
export { zloginfo };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that if kitLogInfo is undefined, it falls back to a console warning instead of causing a crash. 🛠️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue #2: TypeError: Cannot read property 'prefix' of null, js engine: hermes&amp;nbsp;🐞&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Problem ❌&lt;/strong&gt;&lt;br&gt;
This issue was coming from the zego-callkit-react-native library. On iOS, it threw a warning, but on Android, the app crashed abruptly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&amp;nbsp;🧐&lt;/strong&gt;&lt;br&gt;
The problem was in the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Prefix = ZegoCallKitNativeModule.prefix;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using Hermes, ZegoCallKitNativeModule was sometimes null, causing an error when trying to access prefix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution ✅&lt;/strong&gt;&lt;br&gt;
I fixed it by modifying this line to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Platform } from 'react-native';
const Prefix = Platform.OS == 'ios' ? ZegoCallKitNativeModule.prefix : '';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that on Android, the app does not crash due to a null reference. 🛠️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applying Patches for These Fixes&amp;nbsp;🩹&lt;/strong&gt;&lt;br&gt;
To ensure these changes persist across updates, I used the patch-package tool. Here's how I applied and committed these patches:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install patch-package 📦&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn add patch-package postinstall-postinstall&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Make the Changes and Save the Patch&amp;nbsp;📝&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npx patch-package @zegocloud/zego-uikit-prebuilt-call-rn&lt;br&gt;
 npx patch-package zego-callkit-react-native&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Ensure Patch is Applied Automatically 🔄&lt;/strong&gt;&lt;br&gt;
Add this script to package.json:&lt;br&gt;
&lt;code&gt;"scripts": {&lt;br&gt;
  "postinstall": "patch-package"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, whenever a developer runs yarn install, the patches will be applied automatically. 🛠️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Push Patches to GitHub&amp;nbsp;🚀&lt;/strong&gt;&lt;br&gt;
I committed the patches so that other developers on my team could use them:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git add patches/&lt;br&gt;
git commit -m "Fix Zego issues with patch-package"&lt;br&gt;
git push origin main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contributing to Open Source&amp;nbsp;🤝&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I also created pull requests (PRs) to contribute these fixes upstream. If merged, we won't need the patches anymore. Here's my PR for @zegocloud/zego-uikit-prebuilt-call-rn:&lt;br&gt;
&lt;a href="https://github.com/ZEGOCLOUD/zego_uikit_prebuilt_call_rn/pull/14" rel="noopener noreferrer"&gt;🔗 PR #14 - Fix kitLogInfo Issue&lt;br&gt;
&lt;/a&gt;Unfortunately, I couldn't find zego-callkit-react-native on GitHub, so I had to rely on patching for that one. 😕&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion 🎯&lt;/strong&gt;&lt;br&gt;
``&lt;br&gt;
If you're working with Zego Call Kit and facing these frustrating issues, I hope this guide helps you save time. Let me know if you encounter any other problems - let's work together to improve these libraries! 🚀&lt;br&gt;
Feel free to share your thoughts in the comments or contribute to the PR to get these fixes merged! 🔥&lt;/p&gt;

</description>
      <category>zegocloud</category>
      <category>reactnative</category>
      <category>calls</category>
      <category>callkit</category>
    </item>
    <item>
      <title>🚀 DeepSeek AI: A New Challenger in AI Coding Assistants?</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Wed, 29 Jan 2025 13:26:04 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/deepseek-ai-a-new-challenger-in-ai-coding-assistants-383e</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/deepseek-ai-a-new-challenger-in-ai-coding-assistants-383e</guid>
      <description>&lt;p&gt;As a developer, AI coding assistants have become an essential part of my workflow - whether it's writing code, debugging, or optimizing logic. I've relied heavily on tools like Codium and ChatGPT, which have been instrumental in enhancing productivity.&lt;br&gt;
Recently, I decided to put DeepSeek AI to the test, using my usual evaluation method: real-world coding tasks, including refactoring, logic corrections, and React Native improvements. I even challenged it with a complex Redux bug, where clearing the user's state was crashing the app. How did it perform compared to my go-to, ChatGPT? Let's dive in! 🔍&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Handling Standard Coding&amp;nbsp;Tasks&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;ChatGPT:&lt;/strong&gt;&lt;br&gt;
&amp;nbsp;✅ Delivered structured responses with concise explanations.&lt;br&gt;
&amp;nbsp;✅ Used modern ES6+ features for better readability.&lt;br&gt;
&amp;nbsp;✅ Ensured immutability where required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DeepSeek AI:&lt;/strong&gt;&amp;nbsp;&lt;br&gt;
 ❌ Provided a functional response but lacked code organization.&lt;br&gt;
&amp;nbsp;❌ Less emphasis on readability and best practices.&lt;br&gt;
&amp;nbsp;❌ Maintained much of the original structure without significant improvements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwxwhaejvg7n45tmtnry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwxwhaejvg7n45tmtnry.png" alt="Image description" width="800" height="723"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔥 Tackling a Complex Redux&amp;nbsp;Bug&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;ChatGPT:&lt;/strong&gt;&lt;br&gt;
&amp;nbsp;❌ Identified the issue and suggested a fix, but responses were more verbose.&lt;br&gt;
&amp;nbsp;❌ Provided additional explanations - helpful for learning but not strictly necessary.&lt;br&gt;
&amp;nbsp;❌ Suggested a similar solution but didn't highlight Immer's role in Redux Toolkit as clearly as DeepSeek AI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fre4ophfd51sqdy356xt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fre4ophfd51sqdy356xt7.png" alt="Image description" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DeepSeek AI:&lt;/strong&gt;&lt;br&gt;
&amp;nbsp;✅ Quickly pinpointed the issue - improper state handling in the reducer.&lt;br&gt;
&amp;nbsp;✅ Offered a clear, concise fix and explained potential issues.&lt;br&gt;
&amp;nbsp;✅ Suggested using Object.assign and delete for safer state mutations.&lt;br&gt;
&amp;nbsp;✅ Response was detailed, actionable, and straight to the point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚖️ DeepSeek AI vs. ChatGPT: Strengths &amp;amp; Weaknesses&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;🔹 DeepSeek AI&lt;/strong&gt;&lt;br&gt;
&amp;nbsp;✔️ Strengths: Concise, highly practical, and solution-focused. It understood the problem's context well and delivered an efficient fix.&lt;br&gt;
&amp;nbsp;❌ Weaknesses: Lacked in-depth explanations, which might be a downside for those who want to learn the underlying concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 ChatGPT&lt;/strong&gt;&lt;br&gt;
&amp;nbsp;✔️ Strengths: Great for learning! Its detailed responses provide valuable insights into why a solution works.&lt;br&gt;
&amp;nbsp;❌ Weaknesses: Sometimes overly verbose, making it harder to extract the exact solution quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏆 My&amp;nbsp;Verdict&lt;/strong&gt;&lt;br&gt;
For me, ChatGPT wins because of its detailed explanations, making it the best for learning, deep diving into solutions, and truly understanding problems. DeepSeek AI is promising, but it still needs time to evolve and refine its precision. That said, it's clearly in the race and could disrupt the competition at any moment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 DeepSeek's Game-Changing AI&amp;nbsp;Approach&lt;/strong&gt;&lt;br&gt;
DeepSeek isn't just about coding - it's shaking up AI computing and even challenging Nvidia.&lt;br&gt;
Here's how they trained a model matching GPT-4 and Claude for just $5M (vs. the usual $100M+):&lt;br&gt;
🔹 Smarter Math - Reduced memory usage by 75% using 8-bit precision without sacrificing accuracy.&lt;br&gt;
🔹 Faster Reading - Processes entire phrases instead of one word at a time, making it twice as fast while keeping 90% accuracy.&lt;br&gt;
🔹 Expert System - Activates only the relevant AI parameters, running smaller, task-specific models - cutting compute costs by 95%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ A Nightmare for&amp;nbsp;Nvidia?&lt;/strong&gt;&lt;br&gt;
Nvidia makes billions selling $40K AI chips with huge profit margins. Until now, companies had no choice but to buy thousands of them. But DeepSeek's breakthroughs mean high-end AI can run efficiently on fewer GPUs - or even standard gaming cards. If this trend continues, Nvidia's AI hardware dominance is at risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔥 Final&amp;nbsp;Thoughts&lt;/strong&gt;&lt;br&gt;
Both DeepSeek AI and ChatGPT are powerful, but they serve different purposes.&lt;br&gt;
✅ For quick, no-fluff coding solutions: DeepSeek AI is a strong contender.&lt;br&gt;
✅ For in-depth learning and problem-solving: ChatGPT remains my top choice.&lt;br&gt;
AI is evolving fast - who do you think will dominate? Let's discuss! 👇&lt;/p&gt;

</description>
      <category>deepseek</category>
      <category>chatgpt</category>
      <category>ai</category>
      <category>coding</category>
    </item>
    <item>
      <title>🚨 Error occurred prerendering page "/" ? Here's the Fix! 🚨</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Fri, 17 Jan 2025 09:39:15 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/error-occurred-prerendering-page-heres-the-fix-5jg</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/error-occurred-prerendering-page-heres-the-fix-5jg</guid>
      <description>&lt;p&gt;If you're trying out the new Next.js API routes and running into problems fetching data during npm run build, you're not alone. Many developers are encountering this issue because the API route behavior has slightly changed in Next.js. Even after hours of digging through the docs, the solution might not be obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;br&gt;
By default, Next.js tries to optimize performance with static rendering and caching. This is great for speed but can cause issues when you're fetching dynamic data that changes frequently or needs to bypass caching during build time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;&lt;br&gt;
To ensure your data fetching works as expected, you need to override Next.js' default caching behavior. Add these two lines to the top of your file where you're fetching the data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const dynamic = "force-dynamic";
export const fetchCache = "force-no-store";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why This Works&lt;/strong&gt;&lt;br&gt;
dynamic = "force-dynamic": Forces the page to render dynamically instead of statically.&lt;br&gt;
fetchCache = "force-no-store": Disables caching for your fetch calls, ensuring you're always fetching fresh data.&lt;/p&gt;

&lt;p&gt;Example Code&lt;br&gt;
Here’s how it looks in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const dynamic = "force-dynamic";
export const fetchCache = "force-no-store";

const getData = async () =&amp;gt; {
  const res = await fetch("https://your-api-url/api/posts");
  if (!res.ok) throw new Error("Failed to fetch data");
  return res.json();
};

const Blog = async () =&amp;gt; {
  const data = await getData();
  return data.map((item) =&amp;gt; &amp;lt;div key={item.id}&amp;gt;{item.title}&amp;lt;/div&amp;gt;);
};

export default Blog;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Final Step&lt;/strong&gt;&lt;br&gt;
After making this change, run &lt;code&gt;npm run build&lt;/code&gt;again, and your problem should be solved! 🎉&lt;/p&gt;

&lt;p&gt;Hope this saves you hours of debugging. Thank me later 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Integrate Tabby in React Native: A Step-by-Step Guide</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Sun, 22 Dec 2024 16:59:26 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/how-to-integrate-tabby-in-react-native-a-step-by-step-guide-3ja</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/how-to-integrate-tabby-in-react-native-a-step-by-step-guide-3ja</guid>
      <description>&lt;p&gt;Integrating Tabby into your React Native app can be a seamless process, but there’s no comprehensive guide available online that provides a step-by-step approach. This article consolidates information from multiple sources to give you a clear roadmap for implementing Tabby in your React Native app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install Tabby SDK&lt;/strong&gt;&lt;br&gt;
To get started, you need to install the Tabby SDK for React Native. Run the following command in your project directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i tabby-react-native-sdk&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Update Platform-Specific Configurations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iOS Configuration
For iOS, make sure to update your Info.plist file with the following permissions:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;key&amp;gt;NSCameraUsageDescription&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;This allows Tabby to take a photo&amp;lt;/string&amp;gt;
&amp;lt;key&amp;gt;NSPhotoLibraryUsageDescription&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;This allows Tabby to select a photo&amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can customize the descriptions to suit your app.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Configuration
For Android, add these permissions to your &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;uses-permission android:name=”android.permission.CAMERA” /&amp;gt;
&amp;lt;uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE” /&amp;gt;
&amp;lt;uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These permissions ensure Tabby can access the necessary resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Initialize Tabby in Your App&lt;/strong&gt;&lt;br&gt;
To initialize Tabby, add the following code to your app’s entry point &lt;code&gt;(App.tsx or index.js)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Tabby} from 'tabby-react-native-sdk';

Tabby.setApiKey('__API_KEY_HERE__');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Tabby.setApiKey() method sets your API key, allowing your app to authenticate with Tabby's backend services.&lt;/p&gt;

&lt;p&gt;Replace &lt;strong&gt;API_KEY_HERE&lt;/strong&gt; with your Tabby API key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create the Payment Flow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define the Payment Data
In your cart screen, set up the payment data required by Tabby:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const customerPayment = {
  amount: 340.0,
  currency: 'SAR',
  buyer: {
    email: 'successful.payment@tabby.ai',
    phone: '+971500000001',
  },
};

const myTestPayment = {
  merchant_code: 'your merchant code',
  lang: 'en',
  payment: customerPayment,
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The customerPayment object defines the buyer's payment details, such as amount, currency, and contact information. The myTestPayment object includes merchant-specific details like merchant_code and preferred language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a Session Trigger Button&lt;/strong&gt;&lt;br&gt;
Add a button to your UI to trigger the session creation process&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Button title="Proceed with Tabby" onPress={createCheckoutSession} /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This button triggers the createCheckoutSession function when pressed, initiating the payment process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implement the Session Creation Logic&lt;/strong&gt;&lt;br&gt;
Handle the button press with the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const createCheckoutSession = async () =&amp;gt; {
  try {
    const {sessionId, paymentId, availableProducts} =
      await Tabby.createSession(myTestPayment);
    navigation.navigate('TabbyWebViewScreen', {
      url: availableProducts[0].webUrl,
    });
  } catch (error) {
    if (error.response) {
      console.error('Response:', error.response);
      console.error('Status:', error.response.status);
      console.error('Data:', error.response.data);
    }
    console.error('Error creating Tabby checkout session', error);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Tabby.createSession() method creates a checkout session with the payment data. If successful, the response includes session details like sessionId and the checkout URL. The user is then navigated to a new screen (TabbyWebViewScreen) to complete the payment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Create a Tabby WebView Screen&lt;/strong&gt;&lt;br&gt;
Set up a new screen to display the Tabby checkout flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import {View, StyleSheet, Button} from 'react-native';
import {useNavigation, useRoute} from '@react-navigation/native';
import {TabbyPaymentWebView} from 'tabby-react-native-sdk';

const TabbyWebViewScreen = () =&amp;gt; {
  const navigation = useNavigation();
  const route = useRoute();
  const {url} = route.params;

  const handlePaymentResult = message =&amp;gt; {
    switch (message) {
      case 'authorized':
        console.log('Payment Authorized');
        navigation.goBack();
        break;
      case 'rejected':
        console.log('Payment Rejected');
        navigation.goBack();
        break;
      case 'close':
        console.log('Checkout Closed');
        navigation.goBack();
        break;
      case 'expired':
        console.log('Session Expired');
        navigation.goBack();
        break;
      default:
        break;
    }
  };

  return (
    &amp;lt;View style={styles.container}&amp;gt;
      &amp;lt;View style={styles.webViewContainer}&amp;gt;
        &amp;lt;TabbyPaymentWebView
          url={url}
          onBack={() =&amp;gt; navigation.goBack()}
          onResult={handlePaymentResult}
        /&amp;gt;
      &amp;lt;/View&amp;gt;
      &amp;lt;Button title="Go Back" onPress={() =&amp;gt; navigation.goBack()} /&amp;gt;
    &amp;lt;/View&amp;gt;
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  webViewContainer: {
    marginTop: 50,
    height: '95%',
    backgroundColor: 'blue',
  },
});

export default TabbyWebViewScreen;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The TabbyPaymentWebView component loads the checkout URL and displays it in a web view.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The handlePaymentResult function handles the payment outcome (e.g., authorized, rejected, or expired) and redirects the user accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A “Go Back” button allows users to return to the previous screen.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Handle Payment Results&lt;/strong&gt;&lt;br&gt;
The handlePaymentResult function manages user redirection based on payment outcomes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;authorized:&lt;/code&gt;Payment was successful.&lt;br&gt;
&lt;code&gt;rejected:&lt;/code&gt; Payment was declined.&lt;br&gt;
&lt;code&gt;close:&lt;/code&gt; User closed the checkout process.&lt;br&gt;
&lt;code&gt;expired:&lt;/code&gt; Session expired.&lt;br&gt;
Use these outcomes to guide the user experience in your app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/tabby-react-native-sdk" rel="noopener noreferrer"&gt;Tabby React Native SDK&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.tabby.ai/pay-in-4-custom-integration/mobile-sdks/react-native-sdk" rel="noopener noreferrer"&gt;Tabby Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/tabby-ai/react-native-example" rel="noopener noreferrer"&gt;Tabby React Native Example&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Explore these links to dive deeper into Tabby features and advanced use cases.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>tabby</category>
      <category>mobile</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Custom Apple Pay Integration in React Native with Native</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Mon, 16 Dec 2024 11:17:44 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/custom-apple-pay-integration-in-react-native-with-nativ-3po8</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/custom-apple-pay-integration-in-react-native-with-nativ-3po8</guid>
      <description>&lt;p&gt;&lt;strong&gt;Why Build Custom Solutions Over Libraries in React Native?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While libraries simplify integrations in React Native, they often come with limitations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deprecated Libraries:&lt;/strong&gt; Updates and support can cease, leaving projects vulnerable.&lt;br&gt;
&lt;strong&gt;Feature Limitations:&lt;/strong&gt; Libraries may not meet all use cases.&lt;br&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; Custom solutions offer more control for unique requirements.&lt;br&gt;
Custom native modules ensure scalability and precision. Here’s how to integrate Apple Pay natively in React Native for iOS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Use Apple Pay in React Native?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apple Pay enables secure, seamless payments with encrypted card details. A React Native integration aligns with Apple’s security standards while enhancing the user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Before proceeding, you must create a Merchant ID and configure your project in Xcode. Follow &lt;a href="https://developer.apple.com/documentation/passkit/setting-up-apple-pay" rel="noopener noreferrer"&gt;Apple’s official documentation&lt;/a&gt; to complete prerequisites.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to Create a Custom Apple Pay Module&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Create a Swift Module&lt;/strong&gt;&lt;br&gt;
Add an ApplePayModule.swift file to your iOS project:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payment Request Parameters:&lt;/strong&gt; Define merchant ID, supported networks, and payment details.&lt;br&gt;
&lt;strong&gt;Can Make Payments:&lt;/strong&gt; Check device capability with PKPaymentAuthorizationController.canMakePayments().&lt;br&gt;
&lt;strong&gt;Request Payment:&lt;/strong&gt; Present the Apple Pay sheet and handle authorization using React Native callbacks (RCTPromiseResolveBlock/RCTPromiseRejectBlock).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Bridge the Module&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use ApplePayModule.m to bridge Swift and React Native, exposing methods like canMakePayments and requestPayment to JavaScript.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;3. Create a Hook&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The useApplePay hook consolidates Apple Pay operations, feel free to add currencies and countries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;canMakePayments:&lt;/strong&gt; Validates device compatibility.&lt;br&gt;
&lt;strong&gt;requestPayment:&lt;/strong&gt; Handles the payment flow.&lt;br&gt;
&lt;strong&gt;handleApplePay:&lt;/strong&gt; Combines the above for a seamless user experience.&lt;br&gt;
Centralized logic for checking availability and managing payments.&lt;br&gt;
Comprehensive error handling.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;4. Use the Custom Module&lt;/strong&gt;&lt;br&gt;
Here’s a React Native component example leveraging the module:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Custom native modules are ideal when libraries fall short or become deprecated. A native Apple Pay integration:&lt;/p&gt;

&lt;p&gt;Ensures a secure payment flow.&lt;br&gt;
Aligns with Apple’s standards.&lt;br&gt;
Offers control and flexibility for unique project needs.&lt;br&gt;
This approach equips you with a robust, scalable solution for seamless payments in React Native apps.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>applepay</category>
      <category>ios</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Simple Yet Handy React Native Hooks</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Tue, 06 Aug 2024 19:10:41 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/simple-yet-handy-react-native-hooks-515l</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/simple-yet-handy-react-native-hooks-515l</guid>
      <description>&lt;p&gt;React Native developers often encounter common tasks that require repetitive code, such as fetching data. To streamline this task, here is a custom hook: useFetch. This hook is not only simple and easy to use but also cater to edge cases, making your development process smoother.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useFetch Hook&lt;/strong&gt;&lt;br&gt;
The useFetch hook simplifies the process of fetching data from an API, managing the loading state, and handling errors gracefully. It even checks for network connectivity before attempting a fetch, ensuring your app remains robust in various conditions.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Usage Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Effortless Parallax in React Native</title>
      <dc:creator>Muhammad haris baig</dc:creator>
      <pubDate>Mon, 05 Aug 2024 11:46:21 +0000</pubDate>
      <link>https://dev.to/muhammad_harisbaig_1268d/effortless-parallax-in-react-native-3l3a</link>
      <guid>https://dev.to/muhammad_harisbaig_1268d/effortless-parallax-in-react-native-3l3a</guid>
      <description>&lt;p&gt;Hey everyone! If you're searching for a painless and straight forward solution to your parallax issues, look no further! I've got a perfect, easy-to-digest solution for creating a parallax effect with a sticky header, a hide-able parallax view, and a scrollable container that activates once the parent scroll is finished.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating a parallax effect in React Native can be tricky, especially when trying to synchronize scrolling between a parent view and nested views. Common issues include the parallax view not hiding correctly, the child scroll view not activating at the right time, and the sticky header not behaving as expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The following code solves these problems by using a combination of React Native and react-native-reanimated to manage the scroll events efficiently. The solution ensures that the sticky header remains in place, the parallax view hides as the user scrolls up, and the nested scroll view becomes scrollable when the parent scroll is completed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the&amp;nbsp;Code:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can copy and paste the following code to get started:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;How It&amp;nbsp;Works:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sticky Header: The header changes color based on the scroll position, remaining visible at the top of the screen until the user scrolls to the bottom of the parent view.&lt;br&gt;
Parallax View: The parallax section hides as the user scrolls up, creating a smooth transition effect.&lt;br&gt;
Scrollable Container: The nested scroll view becomes scrollable only after the parent scroll view reaches the bottom, ensuring a seamless user experience.&lt;/p&gt;

&lt;p&gt;This solution effectively manages the scrolling behavior between the parent and child views, providing a smooth and visually appealing parallax effect. Feel free to use and modify the code as needed for your projects!&lt;/p&gt;

&lt;p&gt;Happy coding! 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9yw5djrahn8wjtsohaj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9yw5djrahn8wjtsohaj.gif" alt="Image description" width="600" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please consider sharing your experiences and improvements in the comments below. Let's keep the learning going!&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>parallax</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
