<?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: Jacob Park</title>
    <description>The latest articles on DEV Community by Jacob Park (@eatnug).</description>
    <link>https://dev.to/eatnug</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F446585%2Fab5ed2c8-18c1-4eff-8c0c-a13ed394ce4d.jpeg</url>
      <title>DEV Community: Jacob Park</title>
      <link>https://dev.to/eatnug</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eatnug"/>
    <language>en</language>
    <item>
      <title>Codepush-fy your react-native app in 5 minutes! 🚀</title>
      <dc:creator>Jacob Park</dc:creator>
      <pubDate>Wed, 23 Sep 2020 06:13:17 +0000</pubDate>
      <link>https://dev.to/eatnug/codepush-fy-your-react-native-app-in-5-minutes-2el7</link>
      <guid>https://dev.to/eatnug/codepush-fy-your-react-native-app-in-5-minutes-2el7</guid>
      <description>&lt;h2&gt;
  
  
  What is codepush?
&lt;/h2&gt;

&lt;p&gt;Codepush is awesome tool that makes it possible to bypass store review when updating react-native(or cordova) apps. &lt;/p&gt;

&lt;p&gt;It works like cloud storage of app bundle. After you set everything up and publish your app to the market, on every launch your app can check if there's a new version and updates itself. &lt;/p&gt;

&lt;p&gt;It supports iOS, android and windows apps created with react-native or cordova. &lt;/p&gt;

&lt;p&gt;They say it updates only javascript bundle(when it's RN app), so some updates including assets or native code might cause apps to crash and roll back to older version.&lt;/p&gt;

&lt;p&gt;But while using this tool for about four months, no such accident has ever happened. So unless you add native modules or code some out-of-js stuff, you don't have to worry about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I use it?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install Appcenter-cli
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn global add appcenter-cli

or

npm i &lt;span class="nt"&gt;-g&lt;/span&gt; appcenter-cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Add your app and deployment track to Appcenter.
&lt;/h3&gt;

&lt;p&gt;First, you should login to appcenter using &lt;code&gt;appcenter-cli&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;appcenter login &lt;span class="c"&gt;# browser will open up. after you login to appcenter, you'll get auth code to type in terminal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you need to create an app ( not real application, just think this as remote repository of app bundle ) to appcenter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# change appname and os as you want&lt;/span&gt;
appcenter apps create &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;appname&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;os&lt;span class="o"&gt;}(&lt;/span&gt;Android/iOS&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; React-Native
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In production, I create two apps named &lt;code&gt;appname-ios, appname-android&lt;/code&gt; each. After this, you can add deployment track of your app. Consider it as a branch of your remote app bundle repository. You can create multiple tracks and control those different update streams seperately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;appcenter codepush deployment add &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;username/appname&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;trackname&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When you do this, you'll get a deployment key on your terminal. You will need this, copy it.  If you cleared your terminal by accident, you can re-gain it by this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;appcenter codepush deployment list &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;username/appname&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Add codepush to your app.
&lt;/h3&gt;

&lt;p&gt;Add codepush dependency on your react-native project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add react-native-code-push
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Setting up iOS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Add native dependency for iOS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At your root directory of the react-native project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ios &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pod &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;AppDelegate.m&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Import header for codepush.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#import "AppDelegate.h"
&lt;/span&gt;
&lt;span class="cp"&gt;#import &amp;lt;CodePush/CodePush.h&amp;gt; // codepush add this line
&lt;/span&gt;
&lt;span class="cp"&gt;#import &amp;lt;React/RCTBridge.h&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And change url that react-native uses to read source bundle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NSURL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;sourceURLForBridge&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="n"&gt;RCTBridge&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;bridge&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cp"&gt;#if DEBUG
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;RCTBundleURLProvider&lt;/span&gt; &lt;span class="nf"&gt;sharedSettings&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nf"&gt;jsBundleURLForBundleRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;@"index"&lt;/span&gt; &lt;span class="nf"&gt;fallbackResource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="cp"&gt;#else
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;NSBundle&lt;/span&gt; &lt;span class="nf"&gt;mainBundle&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nf"&gt;URLForResource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;@"main"&lt;/span&gt; &lt;span class="nf"&gt;withExtension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;@"jsbundle"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;  
    &lt;span class="c1"&gt;// change the line above to the below&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CodePush&lt;/span&gt; &lt;span class="nf"&gt;bundleURL&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;Info.plist&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you should add codepush deployment key and http exception domain to &lt;code&gt;Info.plist&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First you should notify your app to which remote repository to access by setting deployment key. Add key &lt;code&gt;CodePushDeploymentKey&lt;/code&gt; to your &lt;code&gt;Info.plist&lt;/code&gt; and set value for this. The key that you've copied above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
  ...
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;CodePushDeploymentKey&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;mydeploymentkey&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;

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



&lt;p&gt;And you should allow HTTPS network access to download app bundle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAppTransportSecurity&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAllowsArbitraryLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionDomains&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;codepush.appcenter.ms&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionAllowsInsecureHTTPLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, your &lt;code&gt;Info.plist&lt;/code&gt; will be like below and iOS part of your app is ready to codepush.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;CodePushDeploymentKey&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;mydeploymentkey&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
  ...
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAppTransportSecurity&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAllowsArbitraryLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionDomains&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;codepush.appcenter.ms&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionAllowsInsecureHTTPLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;localhost&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionAllowsInsecureHTTPLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Setting up Android
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;codepush.gradle&lt;/code&gt;to &lt;code&gt;android/app/build.gradle&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/react-native/react.gradle"&lt;/span&gt;
&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/react-native-code-push/android/codepush.gradle"&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;MainApplication.java&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;// 1. import codepush package&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.microsoft.codepush.react.CodePush&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainApplication&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ReactApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ReactNativeHost&lt;/span&gt; &lt;span class="n"&gt;mReactNativeHost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReactNativeHost&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="c1"&gt;// 2. override getJSBundleFile &lt;/span&gt;
        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getJSBundleFile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;CodePush&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJSBundleFile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add deployment key to &lt;code&gt;strings.xml&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The same key again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt; &lt;span class="nt"&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;string&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"app_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;AppName&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;string&lt;/span&gt; &lt;span class="na"&gt;moduleConfig=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"CodePushDeploymentKey"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;mydeploymentkey&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Actually codepush-fy your app.
&lt;/h3&gt;

&lt;p&gt;You've finished setting your app to access to remote repository on the native side. Now you should tell your react-native code to check version and update itself.&lt;/p&gt;

&lt;p&gt;There could be so many scenarios and options, but I'll explain the easiest one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Consider it's your root Component&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;codePush&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-code-push&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AwesomeWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AwesomeContent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AwesomeWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// set options for codepush.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;codePushOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;checkFrequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;codePush&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CheckFrequency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ON_APP_START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;installMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;codePush&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InstallMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IMMEDIATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// wrap your root component with codepush and let this to be registered in index.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;codepush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codePushOptions&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this case, I set &lt;code&gt;checkFrequency&lt;/code&gt;, &lt;code&gt;installMode&lt;/code&gt; options and just wrapped the root component. But you can trigger version check and update manually with &lt;code&gt;codepush.sync()&lt;/code&gt;. You can read about details at &lt;a href="https://github.com/microsoft/react-native-code-push/blob/master/docs/api-js.md"&gt;codepush api&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Push your code!
&lt;/h3&gt;

&lt;p&gt;All settings are done. You can deploy new app bundle with this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;appcenter codepush release-react &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;username/appname&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;trackname&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# you should do this at the root directory of your react-native project&lt;/span&gt;
&lt;span class="c"&gt;# because it read and run commands from your package.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>reactnative</category>
    </item>
    <item>
      <title>codepush로 react native 앱 심사  없이 업데이트 하기</title>
      <dc:creator>Jacob Park</dc:creator>
      <pubDate>Wed, 23 Sep 2020 02:37:37 +0000</pubDate>
      <link>https://dev.to/eatnug/codepush-react-native-4g84</link>
      <guid>https://dev.to/eatnug/codepush-react-native-4g84</guid>
      <description>&lt;p&gt;&lt;a href="https://eatnug.github.io/mobile/react-native-codepush/"&gt;원문&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  codepush란?
&lt;/h2&gt;

&lt;p&gt;codepush는 react native 혹은 cordova 로 개발한 앱을 번거로운 심사과정 없이 바로 업데이트 할 수 있도록 해주는 서비스입니다. 네이티브 코드라는 막으로 감싸져있는 내부의 코드 번들을 원격 저장소에 업로드 해두고, 로컬 디바이스의 앱 번들과 비교해 차이가 있으면 다시 다운로드 받아 업데이트 하는 형태인 듯 합니다.&lt;/p&gt;

&lt;p&gt;현재 ios (7+), android (4.1+), windows등의 운영체제를 지원하고 있으며, react native 기준으로 v0.14부터 v0.63까지 각각에 맞는 코드푸시 버젼으로 지원하고 있습니다. 또한 공식문서에 따르면 자바스크립트 코드가 아닌 이미지나 동영상등의 애셋을 업데이트 하는데에 제약이 있고, 따라서 이를 소스로 사용하는 &lt;code&gt;Video&lt;/code&gt;나 &lt;code&gt;SliderIOS&lt;/code&gt; 같은 특정 컴포넌트의 업데이트는 지원하지 않는다고 합니다.&lt;/p&gt;

&lt;p&gt;허나 4달 정도 직접 사용해 본 결과 자바스크립트 번들을 통째로 업데이트 할 수 있기 때문에 네이티브 코드를 추가로 작성한다거나 하는 부분이 아니면 업데이트에서 제한을 거의 느낄 수 없었습니다.&lt;/p&gt;

&lt;h2&gt;
  
  
  세팅하기
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. AppCenter CLI 설치하기
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn global add appcenter-cli

or

npm i &lt;span class="nt"&gt;-g&lt;/span&gt; appcenter-cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Appcenter에 앱과 배포트랙 등록하기
&lt;/h3&gt;

&lt;p&gt;우선 &lt;code&gt;appcenter-cli&lt;/code&gt;로 로그인을 합니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;appcenter login &lt;span class="c"&gt;# 웹 브라우저가 켜지면 앱센터에 로그인해서 키를 복사한 후 커맨드라인에 붙여넣으면 됩니다.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;이제 appcenter에 내 앱을 생성하고, 배포트랙을 설정해야합니다. 직접 appcentr 대시보드에 접속해서 진행해도 되지만, cli로는 명령어 한줄로 해결할 수 있으니 활용해봅시다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# appname 과 os 부분을 본인 프로젝트에 맞게 수정해주셔야 합니다.&lt;/span&gt;
appcenter apps create &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;appname&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;os&lt;span class="o"&gt;}(&lt;/span&gt;Android/iOS&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; React-Native
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;실제 프로젝트에서는 &lt;code&gt;appname-ios, appname-android&lt;/code&gt;로 앱 두개를 등록하고 관리하는 형태로 사용하고 있습니다. 이제 각 앱마다 배포트랙을 생성해줍시다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 배포트랙은 말 그대로 배포를 하는 트랙입니다.&lt;/span&gt;
&lt;span class="c"&gt;# 여러개로 설정해서 관리하는 경우도 있다고 하는데 아직 그렇게 깊게 경험해보지는 못했습니다.&lt;/span&gt;
&lt;span class="c"&gt;# 만약 appcenter 대시보드를 이용하면 기본적으로 Staging 그리고 Production 트랙이 생성됩니다.&lt;/span&gt;
&lt;span class="c"&gt;# 마지막에 살펴볼 배포과정에서 트랙 이름을 생략하면 Staging으로 배포를 시도합니다.&lt;/span&gt;
appcenter codepush deployment add &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;username/appname&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;trackname&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;이때 터미널에 배포 키가 보여집니다. 나중에 설정에 사용해야하니 복사해둡시다. 혹시나 놓쳤다면 다음 명령어로 다시 확인할 수 있습니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;appcenter codepush deployment list &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;username/appname&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 프로젝트에 codepush 설치하기
&lt;/h3&gt;

&lt;p&gt;react native 프로젝트에 codepush 디펜던시를 추가합니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react-native-code-push
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  iOS Setup
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;디펜던시 설치&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;react native 프로젝트 루트 디렉토리 기준으로 다음 명령어로 네이티브 디펜던시 설치를 진행합니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ios &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pod &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;AppDelegate.m&lt;/code&gt; 수정하기&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;우선 헤더를 import 해줍니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#import "AppDelegate.h"
&lt;/span&gt;
&lt;span class="cp"&gt;#import &amp;lt;CodePush/CodePush.h&amp;gt; // codepush 헤더 추가
&lt;/span&gt;
&lt;span class="cp"&gt;#import &amp;lt;React/RCTBridge.h&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;그리고 react native가 내부적으로 소스 번들을 불러오는 url을 변경해줍니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NSURL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;sourceURLForBridge&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="n"&gt;RCTBridge&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;bridge&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cp"&gt;#if DEBUG
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;RCTBundleURLProvider&lt;/span&gt; &lt;span class="nf"&gt;sharedSettings&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nf"&gt;jsBundleURLForBundleRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;@"index"&lt;/span&gt; &lt;span class="nf"&gt;fallbackResource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="cp"&gt;#else
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CodePush&lt;/span&gt; &lt;span class="nf"&gt;bundleURL&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Info.plist&lt;/code&gt; 수정하기&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이제 &lt;code&gt;Info.plist&lt;/code&gt;에 코드푸시 배포 키와 HTTP 예외 도메인을 설정해줍시다.&lt;/p&gt;

&lt;p&gt;우선 codepush 원격 저장소의 어떤앱에 접근할지 알려주기 위해 &lt;code&gt;Info.plist&lt;/code&gt;에 아까 확인했던 codepush 배포키를 &lt;code&gt;CodePushDeploymentKey&lt;/code&gt; 키의 값으로 추가합니다.&lt;/p&gt;

&lt;p&gt;이 키는 &lt;code&gt;code-push deployment ls &amp;lt;appName&amp;gt; -k&lt;/code&gt; 명령어로 다시 확인할 수 있습니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
  ...
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;CodePushDeploymentKey&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;mydeploymentkey&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;

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



&lt;p&gt;그리고 코드 번들 업데이트를 위해 원격 저장소에 접근하는 HTTPS 요청을 허용해줘야합니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAppTransportSecurity&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAllowsArbitraryLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionDomains&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;codepush.appcenter.ms&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionAllowsInsecureHTTPLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;최종적인 &lt;code&gt;Info.plist&lt;/code&gt; 의 형태는 다음과 같습니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;CodePushDeploymentKey&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;mydeploymentkey&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
  ...
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAppTransportSecurity&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSAllowsArbitraryLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionDomains&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;codepush.appcenter.ms&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionAllowsInsecureHTTPLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;localhost&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSExceptionAllowsInsecureHTTPLoads&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Android 셋업
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;android/app/build.gradle&lt;/code&gt;에 &lt;code&gt;codepush.gradle&lt;/code&gt;를 추가합니다.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/react-native/react.gradle"&lt;/span&gt;
&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/react-native-code-push/android/codepush.gradle"&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;MainApplication.java&lt;/code&gt;를 업데이트합니다.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;// 1. codepush 패키지를 import 합니다.&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.microsoft.codepush.react.CodePush&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainApplication&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ReactApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ReactNativeHost&lt;/span&gt; &lt;span class="n"&gt;mReactNativeHost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReactNativeHost&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="c1"&gt;// 2. getJSBundleFile method 를 오버라이드 합니다.&lt;/span&gt;
        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getJSBundleFile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;CodePush&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJSBundleFile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;배포키를 &lt;code&gt;strings.xml&lt;/code&gt;에 추가합니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;아까 확인했던 그 배포키입니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt; &lt;span class="nt"&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;string&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"app_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;AppName&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;string&lt;/span&gt; &lt;span class="na"&gt;moduleConfig=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"CodePushDeploymentKey"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;mydeploymentkey&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  4. 실제로 프로젝트에 codepush 적용하기
&lt;/h3&gt;

&lt;p&gt;codepush 세팅이 끝났으니, 실제로 내 앱이 자바스크립트 번들을 원격 저장소에서 받아와서 업데이트 할 수 있도록 코드를 작성해야 합니다. 여러가지 옵션을 설정할 수 있지만 우선 가장 간단한 형태만 알아보겠습니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 최상위 컴포넌트라고 가정합니다.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;codePush&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-code-push&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AwesomeWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AwesomeContent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AwesomeWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// 각종 codepush 관련 옵션을 설정하고&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;codePushOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;checkFrequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;codePush&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CheckFrequency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ON_APP_START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;installMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;codePush&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InstallMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IMMEDIATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 최상위 컴포넌트를 codepush 래퍼로 감싸서 export 시키고, 해당 컴포넌트를 앱에 등록시킵니다.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;codepush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codePushOptions&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;위의 예제는 버젼 체크를 하는 케이스와 업데이트 하는 형태를 고정해두는 형태이지만, &lt;code&gt;codepush.sync&lt;/code&gt; 함수로 동적으로 트리거 할수도 있습니다. 자세한 내용은 &lt;a href="https://github.com/microsoft/react-native-code-push/blob/master/docs/api-js.md"&gt;codepush api&lt;/a&gt;에서 확인할 수 있습니다.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. 배포하기
&lt;/h3&gt;

&lt;p&gt;앱이 세팅되고, appcenter 로그인이 된 상태에서 다음 명령어로 배포할 수 있습니다. 당연한 얘기일 수 있으나, react native 프로젝트 루트 디렉토리에서 진행해야 &lt;code&gt;package.json&lt;/code&gt;을 제대로 읽어서 배포를 수행할 수 있습니다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appcenter codepush release-react -a {username/appname} -d {trackname}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>reactnative</category>
    </item>
  </channel>
</rss>
