

<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>cordova &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/cordova/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Thu, 11 Jan 2018 10:38:02 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>cordova &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>[ionic] console.log() debug</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/ionic-console-log-debug/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/ionic-console-log-debug/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 11 Jan 2018 09:55:20 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[cordova]]></category>
		<category><![CDATA[iOS]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1878</guid>

					<description><![CDATA[這個 console.log() 滿好用的，在c...]]></description>
										<content:encoded><![CDATA[<p>這個 console.log() 滿好用的，在chrome/firebox 也可以顯示在console 裡。</p>
<p>在Android 裡會是顯示成：</p>
<p>I/chromium: [INFO:CONSOLE(198)] &#8220;200&#8221;, source: file:///android_asset/www/build/main.js (198)</p>
<p>在 iOS 的 xcode 裡也會丟出來。</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/ionic-console-log-debug/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[ionic] BUILD FAILED Error code 65 for command: xcodebuild with args&#8230;</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/ionic-build-failed-error-code-65-for-command-xcodebuild-with-args/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/ionic-build-failed-error-code-65-for-command-xcodebuild-with-args/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 10 Jan 2018 09:58:14 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[cordova]]></category>
		<category><![CDATA[Debug]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1856</guid>

					<description><![CDATA[使用指令：ionic cordova build...]]></description>
										<content:encoded><![CDATA[<p>使用指令：<code>ionic cordova build ios</code></p>
<p>得到 Error:</p>
<blockquote>
<p class="p1"><span class="s1">ld: 165 duplicate symbols for architecture x86_64</span></p>
<p class="p1"><span class="s1">clang: error: linker command failed with exit code 1 (use -v to see invocation)</span></p>
<p class="p1"><span class="s1">** BUILD FAILED **</span></p>
<p class="p1"><span class="s1">The following build commands failed:</span></p>
<p class="p1"><span class="s1"> Ld build/emulator/myIonicAirWatch2.app/myIonicAirWatch2 normal x86_64</span></p>
<p class="p1"><span class="s1">(1 failure)</span></p>
<p class="p1"><span class="s1">(node:10536) UnhandledPromiseRejectionWarning: Error code 65 for command: xcodebuild with args: -xcconfig,/Users/max/Documents/cordova/myIonicAirWatch2/platforms/ios/cordova/build-debug.xcconfig,-workspace,myIonicAirWatch2.xcworkspace,-scheme,myIonicAirWatch2,-configuration,Debug,-sdk,iphonesimulator,-destination,platform=iOS Simulator,name=iPhone X,build,CONFIGURATION_BUILD_DIR=/Users/max/Documents/cordova/myIonicAirWatch2/platforms/ios/build/emulator,SHARED_PRECOMPS_DIR=/Users/max/Documents/cordova/myIonicAirWatch2/platforms/ios/build/sharedpch</span></p>
<p class="p1"><span class="s1">(node:10536) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)</span></p>
<p class="p1"><span class="s1">(node:10536) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.</span></p>
</blockquote>
<p>&nbsp;</p>
<p>ionic 官方文章：Deploying to a Device<br />
<a href="https://ionicframework.com/docs/intro/deploying/">https://ionicframework.com/docs/intro/deploying/</a></p>
<hr />
<p>解法，先刪掉 ios 目錄：</p>
<ol>
<li><code>rm -rf node_modules/ platforms/ios/</code></li>
<li><code>npm i</code></li>
<li><code>ionic cordova build ios</code></li>
</ol>
<p>如果，我是  npm i 取顯示錯誤：</p>
<blockquote>
<p class="p1"><span class="s1">$ rm -rf node_modules/ platforms/ios/</span></p>
<p class="p1"><span class="s1">max$ npm i</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">ERR!</span> <span class="s4">code</span><span class="s1"> E404</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">ERR!</span> <span class="s4">404</span><span class="s1"> Not Found: com.airwatch.awsdkplugin@~1.2.0</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">ERR!</span><span class="s1"> A complete log of this run can be found in:</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">ERR!</span><span class="s1"> <span class="Apple-converted-space">    </span>/Users/max/.npm/_logs/2018-01-09T10_37_53_852Z-debug.log</span></p>
</blockquote>
<p>&nbsp;</p>
<p>應該是 airwatch-sdk-plugin 有檔案不見了，使用下面指令重新安裝：</p>
<blockquote>
<p class="p1"><span class="s1">$ npm i airwatch-sdk-plugin</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">WARN</span> <span class="s4">saveError</span><span class="s1"> ENOENT: no such file or directory, open &#8216;/Users/max/Documents/cordova/package.json&#8217;</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">WARN</span> <span class="s4">enoent</span><span class="s1"> ENOENT: no such file or directory, open &#8216;/Users/max/Documents/cordova/package.json&#8217;</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">WARN</span><span class="s1"> cordova No description</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">WARN</span><span class="s1"> cordova No repository field.</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">WARN</span><span class="s1"> cordova No README data</span></p>
<p class="p1"><span class="s2">npm</span> <span class="s3">WARN</span><span class="s1"> cordova No license field.</span></p>
<p class="p1"><span class="s1">+ airwatch-sdk-plugin@1.2.0</span></p>
<p class="p1"><span class="s1">added 1 package in 4.1s</span></p>
</blockquote>
<hr />
<p>這個指令很奇怪，好像會 cache, 發現在其他空的資料夾裡，也可以下，會下載一些檔案。如果有程式 lock 住的話，可能需要重開機再試一次，避免檔案被 lock 住，也有可能是 「權限」造成的，一般使用者和 root 使用者可以看到的scope 不同，所以使用 npm i 和 sudo npm i 結果會不同！</p>
<p>build 不成功，中間都有log 檔案，要看 log 檔裡寫什麼。</p>
<hr />
<div>在 iOS 平台，如果有修改過 ionic 的 package name, 如果同步上有錯誤，請記得修改這3個檔案：</div>
<div>
<ul class="MailOutline">
<li>config.xml</li>
<li>/platforms/ios/ios.json</li>
<li>/plugins/ios.json</li>
</ul>
</div>
<hr />
<p>試了很久，還是試不出來，可能是中間有什麼設定檔被改壞掉，重新開一個專案：</p>
<blockquote>
<pre>ionic start myApp tabs</pre>
</blockquote>
<p>&nbsp;</p>
<p>修改掉 config.xml 裡的 package id 。再加入我們有使用到plugin 例如：</p>
<blockquote>
<pre>ionic cordova plugin add airwatch-sdk-plugin</pre>
</blockquote>
<p>&nbsp;</p>
<p>再重新 build iOS 一次：</p>
<blockquote>
<pre>ionic cordova build ios --prod</pre>
</blockquote>
<p>居然 build 成功了。</p>
<p>再把之前寫好的 /src/ 裡的檔案 copy 到新的專案裡，就搞定了。</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/ionic-build-failed-error-code-65-for-command-xcodebuild-with-args/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[ionic] How to set Value Input field</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/ionic-how-to-set-value-input-field/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/ionic-how-to-set-value-input-field/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 10 Jan 2018 09:53:34 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[cordova]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1859</guid>

					<description><![CDATA[設定變數值的範例1： You can do it...]]></description>
										<content:encoded><![CDATA[<p>設定變數值的範例1：</p>
<p>You can do it like that:</p>
<p>page.html</p>
<pre class="lang-js prettyprint prettyprinted"><code><span class="pun">&lt;</span><span class="pln">ion</span><span class="pun">-</span><span class="pln">input id</span><span class="pun">=</span><span class="str">"amount"</span><span class="pln"> type</span><span class="pun">=</span><span class="str">"number"</span> <span class="pun">[(</span><span class="pln">ngModel</span><span class="pun">)]=</span><span class="str">"value"</span><span class="pun">&gt;&lt;/</span><span class="pln">ion</span><span class="pun">-</span><span class="pln">input</span><span class="pun">&gt;</span>
<span class="pun">&lt;</span><span class="pln">button </span><span class="pun">(</span><span class="pln">click</span><span class="pun">)=</span><span class="str">"setInput()"</span><span class="pun">&gt;</span><span class="typ">Set</span> <span class="typ">Value</span><span class="pun">&lt;/</span><span class="pln">button</span><span class="pun">&gt;</span></code></pre>
<p>page.ts</p>
<pre class="lang-js prettyprint prettyprinted"><code><span class="kwd">export</span> <span class="kwd">class</span> <span class="typ">Page</span> <span class="pun">{</span><span class="pln">
  value</span><span class="pun">:</span><span class="pln"> number </span><span class="pun">=</span> <span class="lit">0</span><span class="pun">;</span> <span class="com">// Default is 0</span>

  <span class="kwd">constructor</span><span class="pun">()</span> <span class="pun">{}</span><span class="pln">

  setInput</span><span class="pun">()</span> <span class="pun">{</span>
    <span class="kwd">this</span><span class="pun">.</span><span class="pln">value </span><span class="pun">=</span> <span class="lit">42</span><span class="pun">;</span>
  <span class="pun">}</span>
<span class="pun">}</span></code></pre>
<p>By using <code>[(ngModel)]="value"</code> you bind the <code>value</code> variable to that input field. That way it is always updated. If you change it in the UI, it is immediately updated &#8220;in the code&#8221;. And when you update it in your code, it automatically updates in the UI.</p>
<p>You should probably read an Angular 2 tutorial before you continue working on your app. Angular provides many tools to make that sort of thing a lot easier.</p>
<hr />
<p>範例 2：</p>
<p>變數要先定義好在 .ts  檔案裡，不然會跑出 Error: Property does not exist on type</p>
<p>變數定義的範例：public accordition: any;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong> code:</strong></p>
<pre><code>&lt;ion-label&gt;{{charactersRemaining}}&lt;/ion-label&gt;
&lt;form [formGroup]="viewForm" (ngSubmit)="submitView()"&gt;
    &lt;ion-textarea type="text" placeholder="Enter your view here." [(ngModel)]="view.text" formControlName="viewTextArea" rows="6" (ngModelChange)="viewTextChange()"&gt;&lt;/ion-textarea&gt;
    &lt;button ion-button type="submit" block&gt;Send&lt;/button&gt;
&lt;/form&gt;</code></pre>
<p>&nbsp;</p>
<pre><code>  public viewTextChange() {
    var left = this.viewMaxLength-this.view.text.length;

    if (left &lt; 0) {
      this.view.text = '' + this.oldViewText;
      left = this.viewMaxLength-this.view.text.length;
    }

    this.charactersRemaining = (this.viewMaxLength-this.view.text.length) + ' characters remaining.';
    this.oldViewText = this.view.text;

    /* this.view.text = 'frank'; */
  }</code></pre>
<hr />
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/ionic-how-to-set-value-input-field/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[ionic] CORS(Cross Origin Resource Sharing)</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/ionic-corscross-origin-resource-sharing/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/ionic-corscross-origin-resource-sharing/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 09 Jan 2018 08:29:01 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[cordova]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1849</guid>

					<description><![CDATA[在ionic项目中，如果你使用ionic ser...]]></description>
										<content:encoded><![CDATA[<p>在<code>ionic</code>项目中，如果你使用<code>ionic serve</code>或者<code>ionic run</code>,并且开启了动态加载（live reload），且访问了远端服务器的API，那么你就可能会遇到 <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing" target="_blank" rel="noopener">跨域资源共享(CORS)</a> 问题。出现类似下面的错误提示：</p>
<figure class="highlight plain">
<table>
<tbody>
<tr>
<td class="code">
<pre><span class="line">XMLHttpRequest cannot load http://api.ionic.com/endpoint.</span>
<span class="line">No 'Access-Control-Allow-Origin' header is present on the requested resource.</span>
<span class="line">Origin 'http://localhost:8100' is therefore not allowed access.</span></pre>
</td>
</tr>
</tbody>
</table>
</figure>
<p>&nbsp;</p>
<p>Chrome 瀏覽器有插件（套件）可以直接解決這個問題：</p>
<p>使用Allow-Control-Allow-Origin: *插件：</p>
<p>设置-更多工具-扩展程序 找到Allow-Control-Allow-Origin: *插件</p>
<p><a href="https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en-US">https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en-US</a></p>
<p>&nbsp;</p>
<p>那么，什么是CORS？ 为什么在这里会发生这个错误呢？</p>
<h2 id="什么是CORS？">什么是CORS？</h2>
<p>CORS = Cross origin resource sharing <a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS" target="_blank" rel="noopener">跨域资源共享</a><br />
<code>origin</code>是你当前所在页面的主机地址。<br />
如果你在浏览<code>http://ionicframework.com/blog/handling-cors-issues-in-ionic</code>页面，它的<code>origin</code>就是<code>ionicframework.com</code>。在此页面上，如果你要向<code>http://cors.api.com/api</code>发送一个<a href="https://developer.mozilla.org/zh-CN/docs/AJAX/Getting_Started" target="_blank" rel="noopener">AJAX</a>请求,您的主机源将由Origin标头指定，该标头会自动包含在浏览器的CORS请求中。因为<code>ionicframework.com</code>和主机<code>api.com</code>并不匹配，我们从<code>ionicframework.com</code>的请求必须要经过服务器的批准，才能够访问该资源，以Http Options请求头的形式。</p>
<p>如果我们遇到了上面的错误，说明服务器没有给我们的地址<code>ionicframework.com</code>赋予访问该资源的权限。</p>
<p>下面来看一下，当通过<code>ionic serve</code>,<code>ionic run</code>,<code>ionic run -l</code>三种不同方式运行app时，你的<code>origin</code>分别是什么？</p>
<h3 id="在浏览器中运行时">在浏览器中运行时</h3>
<p>在执行<code>ionic serve</code>时，发生了什么？</p>
<ul>
<li>启动了一个本地web服务器</li>
<li>你的浏览器自动打开了指向本地服务器地址的一个页面</li>
</ul>
<p>这时你可以看到你的app加载到了你的浏览器上，地址是<code>http://localhost:8100</code>(如果你选择了localhost)。</p>
<p>这时，你的<code>origin</code>是<code>localhost:8100</code>。</p>
<p>任何发送到主机而不是<code>localhost:8100</code>的AJAX请求，都将以<code>localhost:8100</code>作为其<code>origin</code>，因此需要经过CORS预检请求，来查看是否有权限访问该资源。</p>
<h3 id="在设备上运行时">在设备上运行时</h3>
<p>当执行<code>ionic run</code>时，又发生了些什么呢？</p>
<ul>
<li>应用程序文件被复制到设备（或模拟器）。</li>
<li>app开始运行，然后启动一个设备（或模拟器）上的浏览器来打开这些文件，类似<code>file://some/path/www/index.html</code></li>
</ul>
<p>这样，你的<code>origin</code>将不存在了，因为你正在运行于一个文件（<code>file://</code>）URI。理所当然，你的任何向外请求将不需要通过CORS预检。</p>
<h3 id="在设备上通过自动加载（livereload）运行时">在设备上通过自动加载（livereload）运行时</h3>
<p>执行<code>ionic run -l</code>时，又将发生什么呢？</p>
<ul>
<li>首先启动一个本地web服务器</li>
<li>设备（或模拟器）上app开始运行，启动一个浏览器来开地址<code>http://192.168.1.1:8100</code>（你的本地IP地址）上的文件。</li>
</ul>
<p>这时，你的<code>origin</code>是<code>192.168.1.1:8100</code>。</p>
<p>任何发送到主机而不是<code>192.168.1.1:8100</code>的AJAX请求，都将以<code>192.168.1.1:8100</code>作为其<code>origin</code>，因此需要经过CORS预检请求，来查看是否有权限访问该资源。</p>
<h2 id="在Ionic中处理CORS问题">在Ionic中处理CORS问题</h2>
<p>CORS问题仅仅发生在，当我们以<code>ionic serve</code>或<code>ionic run -l</code>来运行或测试app的时候。</p>
<p>有2种方法来解决这个问题.</p>
<p>第一种，比较容易的方法，是设置远端服务器，让它可以接受所有源的请求。第二种，有时候我们没有权限去修改远端服务器，此时就需要一个不指定源的请求。</p>
<p>我们可以使用代理服务器来实现这个方案。<code>ionic cli</code>给我们提供了一个很方便的配置代理服务器的方法，下面我们看一下如何来实现。</p>
<h2 id="Ionic-CLI代理服务器">Ionic CLI代理服务器</h2>
<p>下面是关于代理（proxy）的一个定义：</p>
<blockquote><p>In computer networks, a proxy server is a server (a computer system or an application) that acts as an intermediary for requests from clients seeking resources from other servers.</p>
<p>在计算机网络中，代理服务器是一个客户端请求的中介服务器（计算机系统或应用），它用于帮助客户端寻找位于其他服务器上的资源。</p></blockquote>
<p>要解决我们在ionic中遇到的CORS问题，我们需要设置一个代理服务器，它接受我们的请求，并向API端点发出新的请求，然后接受响应，并将其转发回我们的应用程序。</p>
<p>由于代理服务器需要向目标发送新的请求，因此请求中将不会有<code>origin</code>(源)，也就不再需要CORS了。 需要非常注意一点是，<strong><code>origin</code>是浏览器自动帮我们添加在请求头中的</strong>。</p>
<p>Ionic CLI具有为客户端请求设置代理服务器的能力，用来帮助您解决CORS问题，下面来看一下Ionic CLI设置代理的方法。</p>
<h2 id="设置代理服务器">设置代理服务器</h2>
<p>再次说明一下，仅仅在<code>ionic serve</code>或<code>ionic run -l</code>的时候需要设置代理。</p>
<p>首先，我们需要在<code>ionic.project</code>（注意，ionic2 cli新版本已经将此文件重命名为<code>ionic.config.json</code>）配置文件中设置代理。 这将告诉Ionic本地服务器监听这些路径并将这些请求转发到目标网址。</p>
<p>在app中，我们需要替换包含endpoint的URLS，并设置为我们的代理服务器地址。（In our app, we will need to replace our endpoint URLS to be set to the proxy server address for when we are running serve or run -l.）</p>
<blockquote><p>什么是<code>endpoint</code>？</p>
<p>在项目中 endpoint有时也写作baseUrl，比如这个<code>http://cors.api.com/api/book/2/detail</code>的endpoint是<code>http://cors.api.com/api</code>，再比如<code>http://localhost:8101/api/user/123</code>的endpoint是<code>http://localhost:8101/api</code>。</p>
<p>笔者没有想到好的中文来替代这个英文单词，所以没有进行翻译，希望小伙伴们能够理解它的意思就好啦<del>~</del></p></blockquote>
<p>我们可以通过设置一些<em>gulp任务</em>，用gulp中的替换模块(replace)来替换出这些URLS，来简化这一步骤。</p>
<p>比较推荐的方法是设置一个Angular Constant来同一设置的endpoint，方便统一进行修改和维护。</p>
<p>下面是操作步骤。我们需要设置一个Angular Service ApiEndpoint来获取数据。</p>
<h2 id="配置代理地址">配置代理地址</h2>
<p>配置代理有两个需要注意的地方。</p>
<ul>
<li><code>path</code>：你在本地Ionic服务器上访问它们的路径</li>
<li><code>proxyUrl</code>：你最终希望通过API调用达到的proxyUrl</li>
</ul>
<p>修改<code>ionic.config.json</code>(旧版本Ionic CLI是<code>ionic.project</code>)：</p>
<figure class="highlight plain">
<table>
<tbody>
<tr>
<td class="code">
<pre><span class="line">{</span>
<span class="line">  "name": "proxy-example",</span>
<span class="line">  "app_id": "",</span>
<span class="line">  "proxies": [</span>
<span class="line">    {</span>
<span class="line">      "path": "/api", </span>
<span class="line">      "proxyUrl": "http://cors.api.com/api"</span>
<span class="line">    }</span>
<span class="line">  ]</span>
<span class="line">}</span></pre>
</td>
</tr>
</tbody>
</table>
</figure>
<p>如上所述，当您请求访问<code>http://localhost:8100/api</code>的ionic服务器时，它会替你代理请求到<code>http://cors.api.com/api</code>上。这样，就不需要CORS了。</p>
<h2 id="设置Angular-Constant">设置Angular Constant</h2>
<p>很容易将你的ApiEndpoint设置为Angular Constant。下面，我们已经将ApiEndpoint指定为我们的代理url。然后，我们就可以使用这个url作为一个常数。</p>
<figure class="highlight plain">
<table>
<tbody>
<tr>
<td class="code">
<pre><span class="line">angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])</span>
<span class="line">.constant('ApiEndpoint', {</span>
<span class="line">  url: 'http://localhost:8100/api'</span>
<span class="line">})</span>

<span class="line">//For the real endpoint, we'd use this</span>
<span class="line">// constant('ApiEndpoint', {</span>
<span class="line">//  url: 'http://cors.api.com/api'</span>
<span class="line">// })</span></pre>
</td>
</tr>
</tbody>
</table>
</figure>
<h2 id="设置Angular-Service">设置Angular Service</h2>
<figure class="highlight plain">
<table>
<tbody>
<tr>
<td class="code">
<pre><span class="line">angular.module('starter.services', [])</span>

<span class="line">//NOTE: We are including the constant `ApiEndpoint` to be used here.</span>
<span class="line">.factory('Api', function($http, ApiEndpoint) {</span>
<span class="line">  console.log('ApiEndpoint', ApiEndpoint)</span>

<span class="line">  var getApiData = function() {</span>
<span class="line">    return $http.get(ApiEndpoint.url + '/tasks')</span>
<span class="line">      .then(function(data) {</span>
<span class="line">        console.log('Got some data: ', data);</span>
<span class="line">        return data;</span>
<span class="line">      });</span>
<span class="line">  };</span>

<span class="line">  return {</span>
<span class="line">    getApiData: getApiData</span>
<span class="line">  };</span>
<span class="line">})</span></pre>
</td>
</tr>
</tbody>
</table>
</figure>
<h2 id="使用Gulp实现URL自动切换">使用Gulp实现URL自动切换</h2>
<p>首先，需要安装<code>replace module</code></p>
<figure class="highlight bash">
<table>
<tbody>
<tr>
<td class="code">
<pre><span class="line">npm install --save replace</span></pre>
</td>
</tr>
</tbody>
</table>
</figure>
<p>然后，我们需要修改<code>gulpfile.js</code>，并添加2个任务，来添加代理地址、移出代理地址。</p>
<figure class="highlight plain">
<table>
<tbody>
<tr>
<td class="code">
<pre><span class="line">// `npm install --save replace`</span>
<span class="line">var replace = require('replace');</span>
<span class="line">//注意下面的文件地址，它是包含你endpoint或baseurl的文件</span>
<span class="line">var replaceFiles = ['./www/js/app.js'];</span>

<span class="line">gulp.task('add-proxy', function() {</span>
<span class="line">  return replace({</span>
<span class="line">    regex: "http://cors.api.com/api",</span>
<span class="line">    replacement: "http://localhost:8100/api",</span>
<span class="line">    paths: replaceFiles,</span>
<span class="line">    recursive: false,</span>
<span class="line">    silent: false,</span>
<span class="line">  });</span>
<span class="line">})</span>

<span class="line">gulp.task('remove-proxy', function() {</span>
<span class="line">  return replace({</span>
<span class="line">    regex: "http://localhost:8100/api",</span>
<span class="line">    replacement: "http://cors.api.com/api",</span>
<span class="line">    paths: replaceFiles,</span>
<span class="line">    recursive: false,</span>
<span class="line">    silent: false,</span>
<span class="line">  });</span>
<span class="line">})</span></pre>
</td>
</tr>
</tbody>
</table>
</figure>
<h2 id="结束语">结束语</h2>
<p>这个教程展示给你了在运行<code>ionic serve</code>或<code>ionic run -l</code>的时候，一个处理CORS问题的方法。</p>
<p>我们知道，如果按这个方法处理，当我们需要在<code>ionic serve</code>和<code>ionic run -l</code>切换的时候，将ApiEndpoint替换出来可能会比较麻烦。因此我们推荐使用gulp在程序启动时自动完成这个过程。</p>
<p>其实，最简单的处理CORS问题的方法，是要求你的api提供服务器来允许所有的<code>origin</code>。但是，有时候我们无法这么做。</p>
<p>使用Angular Constant和replace module会给我们一个愉快的解决方法来处理CORS问题。</p>
<p>如果你需要一个具体的例子，可以看一下这个<a href="https://github.com/driftyco/ionic-proxy-example" target="_blank" rel="noopener">示例工程</a>。</p>
<p>上面说的就是所有的当你访问一个API服务器时，关于处理CORS问题的全部。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/ionic-corscross-origin-resource-sharing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[ionic] 存取 cordova 的 onready</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/ionic-cordova-onready/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/ionic-cordova-onready/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 09 Jan 2018 02:58:56 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[cordova]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1844</guid>

					<description><![CDATA[這個 Platform 不需要去修改 /src/...]]></description>
										<content:encoded><![CDATA[<p>這個 Platform 不需要去修改 /src/app/app.module.ts 檔，直接加到 <code class="lang-ts hljs typescript"><span class="hljs-constructor"><span class="hljs-keyword">constructor</span></span></code> 裡就可以被使用。</p>
<p>URL：<a href="https://ionicframework.com/docs/api/platform/Platform/">https://ionicframework.com/docs/api/platform/Platform/</a></p>
<hr />
<h1 class="api-title">Platform</h1>
<p><a class="improve-v2-docs" href="http://github.com/ionic-team/ionic/edit/master/src/platform/platform.ts#L6">Improve this doc</a></p>
<p>The Platform service can be used to get information about your current device. You can get all of the platforms associated with the device using the <a href="https://ionicframework.com/docs/api/platform/Platform/#platforms">platforms</a>method, including whether the app is being viewed from a tablet, if it&#8217;s on a mobile device or browser, and the exact platform (iOS, Android, etc). You can also get the orientation of the device, if it uses right-to-left language direction, and much much more. With this information you can completely customize your app to fit any device.</p>
<h2><a class="anchor" href="https://ionicframework.com/docs/api/platform/Platform/#usage" name="usage">Usage</a></h2>
<pre><code class="lang-ts hljs typescript"><span class="hljs-keyword">import</span> { Platform } from <span class="hljs-string">'ionic-angular'</span>;

<span class="hljs-keyword">@Component</span>({...})
<span class="hljs-keyword">export</span> MyPage {
  <span class="hljs-constructor"><span class="hljs-keyword">constructor</span>(public plt: Platform) </span>{

  }
}</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/ionic-cordova-onready/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[ionic] http 元件</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/ionic-error-uncaught-in-promise-error-staticinjectorerrorhttp/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/ionic-error-uncaught-in-promise-error-staticinjectorerrorhttp/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 09 Jan 2018 02:26:06 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[cordova]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1842</guid>

					<description><![CDATA[在 ionic 裡使用 http 元件時： ht...]]></description>
										<content:encoded><![CDATA[<p>在 ionic 裡使用 http 元件時：<br />
<a href="https://ionicframework.com/docs/native/http/">https://ionicframework.com/docs/native/http/</a></p>
<p>遇到Error: Uncaught (in promise): Error: StaticInjectorError[HTTP]: 的 error，發生的原因是沒有加入到 providers 清單裡，加入的範例，檔案在 /src/app/app.module.ts :</p>
<h4 id="Add_Plugins_to_Your_App_Module">Add Plugins to Your App&#8217;s Module</h4>
<p>After installing a plugin’s package, add it to your app’s <code class="highlighter-rouge">NgModule</code>.</p>
<div class="language-typescript highlighter-rouge">
<pre class="highlight"><code class="hljs javascript"><span class="p">...</span>

<span class="k"><span class="hljs-keyword">import</span></span> <span class="p">{</span> <span class="nx">Camera</span> <span class="p">}</span> <span class="k"><span class="hljs-keyword">from</span></span> <span class="s1"><span class="hljs-string">'@ionic-native/camera'</span></span><span class="p">;</span>

<span class="p">...</span>

<span class="err">@</span><span class="nx">NgModule</span><span class="p">({</span>
  <span class="p">...</span>

  <span class="na">providers</span><span class="p">:</span> <span class="p">[</span>
    <span class="p">...</span>
    <span class="nx">Camera</span>
    <span class="p">...</span>
  <span class="p">]</span>
  <span class="p">...</span>
<span class="p">})</span>
<span class="k"><span class="hljs-keyword">export</span></span> <span class="kr"><span class="hljs-class"><span class="hljs-keyword">class</span></span></span> <span class="nx"><span class="hljs-class"><span class="hljs-title">AppModule</span></span></span> <span class="p">{</span> <span class="p">}</span>
</code></pre>
</div>
<p>&nbsp;</p>
<hr />
<p>如果是透過 &#8216;@angular/http&#8217; 範例如下：</p>
<p>&nbsp;</p>
<p>&#8216;@angular/http&#8217; 的在 &#8220;/src/app/app.module.ts&#8221; 設定：</p>
<p><strong><span style="color: #ff0000;">import { Http } from &#8216;@angular/http&#8217;;</span></strong><br />
<strong><span style="color: #ff0000;">import { HttpModule } from &#8216;@angular/http&#8217;;</span></strong></p>
<p>..</p>
<p>..</p>
<p>imports: [<br />
BrowserModule,<br />
<span style="color: #ff0000;"><strong>HttpModule,</strong></span><br />
IonicModule.forRoot(MyApp)<br />
],</p>
<hr />
<p><strong>GET Example</strong></p>
<pre><code>this.posts = null;

this.http.get('https://www.reddit.com/r/gifs/top/.json?limit=2&amp;sort=hot').map(res =&gt; res.json()).subscribe(data =&gt; {
    this.posts = data.data.children;
});

console.log(this.posts);
</code></pre>
<p><a href="https://www.joshmorony.com/using-http-to-fetch-remote-data-from-a-server-in-ionic-2/" rel="nofollow noreferrer">https://www.joshmorony.com/using-http-to-fetch-remote-data-from-a-server-in-ionic-2/</a></p>
<p><strong>POST Example</strong></p>
<pre><code>let headers = new Headers();
headers.append('Content-Type', 'application/json');

let body = { 
  message:"do you hear me?"
};

this.http.post('http://spstest.000webhostap..., JSON.stringify(body), {headers: headers})
 .map(res =&gt; res.json())
 .subscribe(data =&gt; {
   console.log(data);
  });
}</code></pre>
<hr />
<p>如果是要取 html 而不是 json，範例：</p>
<p>var response = this.http.get(link);<br />
response.subscribe(<br />
res =&gt; {<br />
console.log(res.text());<br />
let alert = this.alerCtrl.create({<br />
title: &#8216;Responsed!&#8217;,<br />
message: res.text(),<br />
buttons: [&#8216;Ok&#8217;]<br />
});<br />
alert.present()<br />
},<br />
err =&gt; {<br />
console.log(err);<br />
},<br />
() =&gt; console.log(&#8216;call http API Complete&#8217;)<br />
);</p>
<hr />
<div>使用</div>
<div class="">import { Http } from &#8216;@angular/http’;</div>
<div class=""></div>
<div class="">在某些需要穿透 tunnel 的情況下會有錯誤，請改用</div>
<div class="">import { HTTP } from &#8216;@ionic-native/http&#8217;;</div>
<div></div>
<div class="">附註：使用  &#8216;@angular/http’ 只能在 iOS/Android 上開發，沒辦法透過 ionic serve 在PC 上測試。</div>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/ionic-error-uncaught-in-promise-error-staticinjectorerrorhttp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>使用Ionic創建一個簡單的APP</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/create-ionic-app/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/create-ionic-app/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 08 Jan 2018 09:43:51 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[cordova]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1818</guid>

					<description><![CDATA[上次成功建立一個 cordova project...]]></description>
										<content:encoded><![CDATA[<p>上次成功建立一個 cordova project 並 build 到手機，這次要改試 Ionic.</p>
<p>[Cordova] 在 Mac 上安裝 Cordova 與建立第一個 HelloWorld 專案<br />
<a href="https://stackoverflow.max-everyday.com/2017/12/cordova-mac-helloworld/">https://stackoverflow.max-everyday.com/2017/12/cordova-mac-helloworld/</a></p>
<hr />
<p>Ionic的App都是基於Cordova的，所以Cordova工具可以用來構建，部署和測試App。</p>
<p>安裝最新版本的Cordova和Ionic，指令如下：</p>
<blockquote>
<pre>sudo npm install -g cordova ionic</pre>
</blockquote>
<p>&nbsp;</p>
<p>當安裝完成時，試著用一個標籤模版如下圖所示創建一個新的ionic project：</p>
<blockquote>
<pre>ionic start myIonicApp tabs</pre>
</blockquote>
<p>&nbsp;</p>
<p>在建立 ionic project 時，會先問：</p>
<blockquote>
<pre> Would you like to integrate your new app with Cordova to target native iOS and Android?</pre>
</blockquote>
<p>我是選 Yes，因為不知道要選什麼，所以隨便選一個。</p>
<p>建議先註冊一個 ionic 的帳號：</p>
<p><a href="https://dashboard.ionicjs.com/signup">https://dashboard.ionicjs.com/signup</a></p>
<p>第2個問題會問我們：</p>
<blockquote>
<pre>Install the free Ionic Pro SDK and connect your app?</pre>
</blockquote>
<p>選 Yes 的話，需要輸入 ionic email/password.</p>
<p>預設會幫我們把source code 上傳到ionic 的 git 耶：</p>
<blockquote>
<pre>git remote add ionic git@git.ionicjs.com:max32002/myIonicApp.git</pre>
</blockquote>
<p>&nbsp;</p>
<p>切換到 ionic project 目錄，添加ionic平台，如下所示建立app：</p>
<blockquote>
<pre>cd myIonicApp</pre>
</blockquote>
<p>&nbsp;</p>
<p>Run your App 指令：</p>
<blockquote><p>ionic serve</p></blockquote>
<p>ionic 比 cordova 多做很多東西，cordova 要 preview 比較麻煩，用 ionic 方便很多。</p>
<p>&nbsp;</p>
<p>ionic 增加 plugin 方法：</p>
<h2 id="synopsis">Synopsis</h2>
<div class="language-bash highlighter-rouge">
<pre class="highlight"><code class="hljs scss"><span class="gp">$ </span>ionic cordova plugin <span class="o"><span class="hljs-attr_selector">[</span></span><span class="hljs-attr_selector">&lt;action&gt;]</span> <span class="o"><span class="hljs-attr_selector">[</span></span><span class="hljs-attr_selector">&lt;plugin&gt;]</span></code></pre>
</div>
<p>&nbsp;</p>
<p>例如：加入 airwatch plugin</p>
<blockquote>
<pre>ionic cordova plugin add airwatch-sdk-plugin</pre>
</blockquote>
<p>&nbsp;</p>
<p>ionic 加入 button / alert 範例：</p>
<p><a href="https://ionicframework.com/docs/components/#alert">https://ionicframework.com/docs/components/#alert</a></p>
<hr />
<p>html UI 的 demo source code:</p>
<p><a href="https://github.com/ionic-team/ionic-preview-app/blob/master/src/pages/alerts/basic/template.html">https://github.com/ionic-team/ionic-preview-app/blob/master/src/pages/alerts/basic/template.html</a></p>
<pre>&lt;ion-header&gt;
  &lt;ion-navbar&gt;
    &lt;ion-title&gt;Alerts&lt;/ion-title&gt;
  &lt;/ion-navbar&gt;
&lt;/ion-header&gt;

&lt;ion-content padding&gt;
  &lt;button ion-button block color="dark" (click)="doAlert()"&gt;Show Basic Alert&lt;/button&gt;
&lt;/ion-content&gt;</pre>
<hr />
<p>script 的 demo source code:</p>
<p><a href="https://github.com/ionic-team/ionic-preview-app/blob/master/src/pages/alerts/basic/pages.ts">https://github.com/ionic-team/ionic-preview-app/blob/master/src/pages/alerts/basic/pages.ts</a></p>
<pre>import { Component } from '@angular/core';

import { AlertController } from 'ionic-angular';


@Component({
  templateUrl: 'template.html'
})
export class BasicPage {

  constructor(public alerCtrl: AlertController) { }

  doAlert() {
    let alert = this.alerCtrl.create({
      title: 'New Friend!',
      message: 'Your friend, Obi wan Kenobi, just approved your friend request!',
      buttons: ['Ok']
    });
    alert.present()
  }

}</pre>
<hr />
<p>ionic build 成 Andoid/iOS:</p>
<p><a href="https://ionicframework.com/docs/intro/deploying/">https://ionicframework.com/docs/intro/deploying/</a></p>
<p>Android, 透過下面指令就可以 adb build 進手機裡，超神奇！</p>
<blockquote>
<pre>ionic cordova run android --device</pre>
</blockquote>
<p>Sign Android APK</p>
<p>If you want to release your app in the Google Play Store, you have to sign your APK file. To do this, you have to create a new certificate/keystore.</p>
<p>Let’s generate your private key using the keytool command that comes with the JDK:</p>
<div class="language-bash highlighter-rouge">
<pre class="highlight"><code class="hljs css"><span class="hljs-tag">keytool</span> <span class="hljs-tag">-genkey</span> <span class="hljs-tag">-v</span> <span class="hljs-tag">-keystore</span> <span class="hljs-tag">my-release-key</span><span class="hljs-class">.jks</span> <span class="hljs-tag">-keyalg</span> <span class="hljs-tag">RSA</span> <span class="hljs-tag">-keysize</span> 2048 <span class="hljs-tag">-validity</span> 10000 <span class="hljs-tag">-alias</span> <span class="hljs-tag">my-alias</span>
</code></pre>
</div>
<p>You’ll first be prompted to create a password for the keystore. Then, answer the rest of the nice tools’s questions and when it’s all done, you should have a file called my-release-key.jks created in the current directory.</p>
<p><strong>Note</strong>: Make sure to save this file somewhere safe, if you lose it you won’t be able to submit updates to your app!</p>
<p>To sign the unsigned APK, run the jarsigner tool which is also included in the JDK:</p>
<div class="language-bash highlighter-rouge">
<pre class="highlight"><code class="hljs css"><span class="hljs-tag">jarsigner</span> <span class="hljs-tag">-verbose</span> <span class="hljs-tag">-sigalg</span> <span class="hljs-tag">SHA1withRSA</span> <span class="hljs-tag">-digestalg</span> <span class="hljs-tag">SHA1</span> <span class="hljs-tag">-keystore</span> <span class="hljs-tag">my-release-key</span><span class="hljs-class">.jks</span> <span class="hljs-tag">android-release-unsigned</span><span class="hljs-class">.apk</span> <span class="hljs-tag">my-alias</span>
</code></pre>
</div>
<p>This signs the APK in place. Finally, we need to run the zip align tool to optimize the APK. The zipalign tool can be found in <code class="highlighter-rouge">/path/to/Android/sdk/build-tools/VERSION/zipalign</code>. For example, on OS X with Android Studio installed, zipalign is in <code class="highlighter-rouge">~/Library/Android/sdk/build-tools/VERSION/zipalign</code>:</p>
<div class="language-bash highlighter-rouge">
<pre class="highlight"><code class="hljs css"><span class="hljs-tag">zipalign</span> <span class="hljs-tag">-v</span> 4 <span class="hljs-tag">android-release-unsigned</span><span class="hljs-class">.apk</span> <span class="hljs-tag">HelloWorld</span><span class="hljs-class">.apk</span>
</code></pre>
</div>
<p>To verify that your apk is signed run apksigner. The apksigner can be also found in the same path as the zipalign tool:</p>
<div class="language-bash highlighter-rouge">
<pre class="highlight"><code class="hljs css"><span class="hljs-tag">apksigner</span> <span class="hljs-tag">verify</span> <span class="hljs-tag">HelloWorld</span><span class="hljs-class">.apk</span>
</code></pre>
</div>
<p>Now we have our final release binary called HelloWorld.apk and we can release this on the Google Play Store for all the world to enjoy!</p>
<p>All steps can also be found here: <a href="https://developer.android.com/studio/publish/app-signing.html#signing-manually">Android SDK docs</a></p>
<hr />
<p>但我透過上面的指令，實際上會失敗。錯誤訊息如下：</p>
<blockquote>
<pre>(node:4866) UnhandledPromiseRejectionWarning: CordovaError: Could not find an installed version of Gradle either in Android Studio,
or on your system to install the gradle wrapper. Please include gradle 
in your path, or install Android Studio
 at Object.module.exports.check_gradle (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/lib/check_reqs.js:150:18)
 at StudioBuilder.prepEnv (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/lib/builders/StudioBuilder.js:216:23)
 at Api.module.exports.run (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/lib/build.js:154:20)
 at /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/Api.js:342:43
 at _fulfilled (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/node_modules/q/q.js:854:54)
 at self.promiseDispatch.done (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/node_modules/q/q.js:883:30)
 at Promise.promise.promiseDispatch (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/node_modules/q/q.js:816:13)
 at /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/node_modules/q/q.js:624:44
 at runSingle (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/node_modules/q/q.js:137:13)
 at flush (/Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/cordova/node_modules/q/q.js:125:13)
(node:4866) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:4866) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.</pre>
</blockquote>
<p>很多英文字，都看不懂，只好跳過，用 Android Studio 來 import.</p>
<p>在匯入的時候會顯示 Gradle 版本不同，除非你對 Gradle有略懂，還是建議你和我一樣，先跳過 Gradle 版本升級的問題。</p>
<p>&nbsp;</p>
<p>Build iOS Devices</p>
<h3 id="running-your-app-1">Running Your App</h3>
<ol>
<li>Run a production build of your app with <code class="highlighter-rouge">ionic cordova build ios --prod</code></li>
<li>Open the <code class="highlighter-rouge">.xcodeproj</code> file in <code class="highlighter-rouge">platforms/ios/</code> in Xcode</li>
<li>Connect your phone via USB and select it as the run target</li>
<li>Click the play button in Xcode to try to run your app</li>
</ol>
<hr />
<p>附註：直接修改 /src/pages/ 目錄裡的檔案，可以透過 ionic serve 直接看到修改後的結果，但實際上 android 並不是直接去讀取 /src/pages/ 目錄下的檔案，而是讀取</p>
<p class="p1"><span class="s1"> platforms/android/app/src/main/assets/www/build/main.js</span></p>
<p>所以，需要手動執行一下 ionic cordova run android 來轉換 source code 為 javascript.</p>
<hr />
<h4>ionic change package id：</h4>
<p>預設 package id =io.ionic.starter , 設定值在 /config.xml 檔裡：</p>
<blockquote>
<pre>&lt;widget id="io.ionic.starter"</pre>
</blockquote>
<p>修改完設定值，重跑一次</p>
<p class="p1"><span class="s1"> ionic cordova run android</span></p>
<p>所有的設定值就變成預想的結果了。</p>
<p>&nbsp;</p>
<p>附註：似乎還是會有錯誤，訊息如下：</p>
<blockquote><p>$ adb install-multiple -r -t /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/dep/dependencies.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_0.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_2.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_1.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_3.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_4.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_5.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_6.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_7.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_8.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/intermediates/split-apk/debug/slices/slice_9.apk /Users/max/Documents/cordova/myIonicAirWatch2/platforms/android/app/build/outputs/apk/debug/app-debug.apk<br />
Split APKs installed<br />
$ adb shell am start -n &#8220;io.ionic.starter/com.airwatch.gateway.ui.GatewaySplashActivity&#8221; -a android.intent.action.MAIN -c android.intent.category.LAUNCHER<br />
Error while executing: am start -n &#8220;io.ionic.starter/com.airwatch.gateway.ui.GatewaySplashActivity&#8221; -a android.intent.action.MAIN -c android.intent.category.LAUNCHER<br />
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=io.ionic.starter/com.airwatch.gateway.ui.GatewaySplashActivity }<br />
Error type 3<br />
Error: Activity class {io.ionic.starter/com.airwatch.gateway.ui.GatewaySplashActivity} does not exist.</p>
<p>Error while Launching activity</p></blockquote>
<p>修改 Android 的 Preference 參數，在 Build 選項裡，停用掉 Instant run 還是一樣的結果 Q_Q;。</p>
<p>手動修改檔案：</p>
<p>platforms/android/android.json<br />
plugins/android.json</p>
<p>然後一定要<span style="color: #ff0000;"><strong>「關掉 Android Studio」</strong></span>再開啟，就可以了！</p>
<hr />
<p>build iOS ：</p>
<blockquote>
<pre>ionic cordova build ios --prod</pre>
</blockquote>
<p>&nbsp;</p>
<p>附註：修改 app package id, 可能會有「同步」上的錯誤，部份舊的設定值 ionic 不會去修改他，會套用不到 xcode 裡，會造成怎麼 build 出來的 app 都是錯誤的。這個問題的解法有 2：</p>
<p>1：platform remove 再 platform add 一次，而且要先「刪掉舊的 node_modules」資料夾，不然設定值改不掉。</p>
<p>2：找到有問題的地方，手動去修改。這個難度高，需要清楚地知道要去修改 plist 的那一個地方！</p>
<p>&nbsp;</p>
<hr />
<p>要使用 http request 在 ionic 裡：<br />
<a href="https://ionicframework.com/docs/native/http/">https://ionicframework.com/docs/native/http/</a></p>
<h2>Installation</h2>
<ol class="installation">
<li>Install the Cordova and Ionic Native plugins:
<pre><code class="nohighlight">$ ionic cordova plugin add cordova-plugin-advanced-http
$ npm install --save @ionic-native/http
</code></pre>
</li>
<li><a href="https://ionicframework.com/docs/native/#Add_Plugins_to_Your_App_Module">Add this plugin to your app&#8217;s module</a></li>
</ol>
<p>&nbsp;</p>
<h2>Usage</h2>
<pre><code class="lang-typescript hljs"><span class="hljs-keyword">import</span> { HTTP } from <span class="hljs-string">'@ionic-native/http'</span>;

<span class="hljs-constructor"><span class="hljs-keyword">constructor</span>(private http: HTTP) </span>{ }

...

<span class="hljs-keyword">this</span>.http.get(<span class="hljs-string">'http://ionic.io'</span>, {}, {})
  .then(data =&gt; {

    <span class="hljs-built_in">console</span>.log(data.status);
    <span class="hljs-built_in">console</span>.log(data.data); <span class="hljs-comment">// data received by server</span>
    <span class="hljs-built_in">console</span>.log(data.headers);

  })
  .catch(error =&gt; {

    <span class="hljs-built_in">console</span>.log(error.status);
    <span class="hljs-built_in">console</span>.log(error.error); <span class="hljs-comment">// error message as string</span>
    <span class="hljs-built_in">console</span>.log(error.headers);

  });</code></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>資料來源：</p>
<p><a href="https://ionicframework.com/getting-started/">https://ionicframework.com/getting-started/</a></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/create-ionic-app/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Cordova] 存取 Airwatch SDK 範例</title>
		<link>https://stackoverflow.max-everyday.com/2018/01/cordova-airwatch-sdk/</link>
					<comments>https://stackoverflow.max-everyday.com/2018/01/cordova-airwatch-sdk/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 08 Jan 2018 08:30:40 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[cordova]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1829</guid>

					<description><![CDATA[操作步驟如下： 1. 建立一個 Hello Wo...]]></description>
										<content:encoded><![CDATA[<p>操作步驟如下：</p>
<p>1. 建立一個 Hello World 專案：</p>
<blockquote>
<pre>cordova create hello_airwatch com.example.hello_airwatch HelloAirwatch</pre>
</blockquote>
<p>2. 進入 hello_airwatch 目錄下</p>
<blockquote>
<pre>cd hello_airwatch</pre>
</blockquote>
<p>3. 加入了 ios 和 android平台：</p>
<blockquote>
<pre>cordova platform add ios
cordova platform add android</pre>
</blockquote>
<p>4. 加入了 airwatch SDK：</p>
<blockquote>
<pre>cordova plugin add airwatch-sdk-plugin</pre>
</blockquote>
<p>加入 Airwatch SDK 後，服用下列的範例就可以存取到目前的使用者。</p>
<pre><span lang="EN-US">&lt;!DOCTYPE </span><span lang="EN-US">html</span><span lang="EN-US">&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;</span><span lang="EN-US">Device Properties Example</span><span lang="EN-US">&lt;/title&gt;

    &lt;script </span><span lang="EN-US">type=</span><span lang="EN-US">"text/javascript" </span><span lang="EN-US">src=</span><span lang="EN-US">"cordova.js"</span><span lang="EN-US">&gt;&lt;/script&gt;
    &lt;script </span><span lang="EN-US">type=</span><span lang="EN-US">"text/javascript" </span><span lang="EN-US">charset=</span><span lang="EN-US">"utf-8"</span><span lang="EN-US">&gt;

    </span><span lang="EN-US">// Wait for device API libraries to load
    //
    document.addEventListener("deviceready", onDeviceReady, false);

    // device APIs are available
    //
    function onDeviceReady() {
        var element = document.getElementById('deviceProperties');
        element.innerHTML = 'Device Model: 123';

        window.plugins.airwatch.setSDKEventListener(sdkEventCallback);
    }

    function sdkEventCallback(event, info)
    {
        var element = document.getElementById('deviceProperties');
        element.innerHTML = 'event: ' + event;
        if (event === "initSuccess") {
            window.plugins.airwatch.username(usernameEventCallback);
        }
    }

    function usernameEventCallback(successCallback, errorCallback)
    {
        var element = document.getElementById('usernameProperties');
        element.innerHTML = 'username: ' + successCallback;
    }

    </span><span lang="EN-US">&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p </span><span lang="EN-US">id=</span><span lang="EN-US">"deviceProperties"</span><span lang="EN-US">&gt;</span><span lang="EN-US">Loading device properties...</span><span lang="EN-US">&lt;/p&gt;
&lt;p </span><span lang="EN-US">id=</span><span lang="EN-US">"usernameProperties"</span><span lang="EN-US">&gt;</span><span lang="EN-US">Loading username properties...</span><span lang="EN-US">&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</span></pre>
<p>附註：我是使用 Android Studio 去匯入 Cordova 目錄下的 android 目錄，就可以 build 成 apk 了，當然，也可以透過 adb 或其他的 command line 來 build apk ，理論上不需要安裝 Android Studio, 只需要安裝 Android SDK.<br />
附註：如果遇到 build 的 error message, 可能是 airwatch-dsk-plugin 會使用到 aar 格式的檔案, 如果build 的 error message 是：<br />
Error:Failed to resolve: :AirWatchSDK-release<br />
是因為 aar 檔案的檔案沒有被 comiple 成功。解法是把 aar 放到 /app/libs/ 目錄下，就可以正常抓到。</p>
<p>可以 build 成功之後，就可以透過上述的範例存取到 airwatch SDK 所提供的資料。</p>
<p>&nbsp;</p>
<p>Airwatch SDK資料來源：</p>
<p><a href="https://www.npmjs.com/package/airwatch-sdk-plugin">https://www.npmjs.com/package/airwatch-sdk-plugin</a></p>
<p>&nbsp;</p>
<p>附註：</p>
<p>Airwatch plugin 的 build.gradle 裡的設定值：</p>
<blockquote>
<pre>minSdkVersion 14</pre>
</blockquote>
<p>這行可能會造成無法 build 成功，請修改為：</p>
<blockquote>
<pre>minSdkVersion 16</pre>
</blockquote>
<p>也許需要調整：</p>
<ul>
<li>
<p class="p1"><span class="s1">plugins/com.airwatch.awsdkplugin/src/android/build.gradle</span></p>
</li>
<li>
<p class="p1">node_modules/airwatch-sdk-plugin/src/android/build.gradle</p>
</li>
<li>platforms/android/com.airwatch.awsdkplugin/starter-build.gradle</li>
</ul>
<p>&nbsp;</p>
<p>執行結果如下：</p>
<p><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-1832" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2018/01/image001.jpg" alt="" width="720" height="1280" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2018/01/image001.jpg 720w, https://stackoverflow.max-everyday.com/wp-content/uploads/2018/01/image001-338x600.jpg 338w, https://stackoverflow.max-everyday.com/wp-content/uploads/2018/01/image001-576x1024.jpg 576w" sizes="(max-width: 720px) 100vw, 720px" /></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2018/01/cordova-airwatch-sdk/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Cordova] build Android apk</title>
		<link>https://stackoverflow.max-everyday.com/2017/12/cordova-build-android-apk/</link>
					<comments>https://stackoverflow.max-everyday.com/2017/12/cordova-build-android-apk/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 27 Dec 2017 01:48:01 +0000</pubDate>
				<category><![CDATA[Android筆記]]></category>
		<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[cordova]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1763</guid>

					<description><![CDATA[要把 Cordova 的 project bui...]]></description>
										<content:encoded><![CDATA[<p>要把 Cordova 的 project build 成 apk，透過 android studio 滿簡單的，</p>
<p>&nbsp;</p>
<p><img decoding="async" class="alignnone size-full wp-image-1764" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2017/12/Screenshot-2017-12-26-21.16.01.jpg" alt="" width="1554" height="968" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2017/12/Screenshot-2017-12-26-21.16.01.jpg 1554w, https://stackoverflow.max-everyday.com/wp-content/uploads/2017/12/Screenshot-2017-12-26-21.16.01-600x374.jpg 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2017/12/Screenshot-2017-12-26-21.16.01-768x478.jpg 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2017/12/Screenshot-2017-12-26-21.16.01-1024x638.jpg 1024w" sizes="(max-width: 1554px) 100vw, 1554px" /></p>
<p>進入 Android Studio 之後，點選 &#8220;Import project&#8221; 就可以把 Cordova 的 /platforms/android/ 目錄匯入，就可以直接 build 成 apk 了，滿簡單的。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2017/12/cordova-build-android-apk/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Cordova] 在 Mac 上安裝 Cordova 與建立第一個 HelloWorld 專案</title>
		<link>https://stackoverflow.max-everyday.com/2017/12/cordova-mac-helloworld/</link>
					<comments>https://stackoverflow.max-everyday.com/2017/12/cordova-mac-helloworld/#comments</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 26 Dec 2017 04:21:06 +0000</pubDate>
				<category><![CDATA[Cordova筆記]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[cordova]]></category>
		<category><![CDATA[iOS]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=1681</guid>

					<description><![CDATA[1. 先準備好 Android build 環境...]]></description>
										<content:encoded><![CDATA[<p>1. 先準備好 Android build 環境，直接安裝 Android Studio + Xcode.</p>
<p>&nbsp;</p>
<p>2. 在 Mac 上可以加到 ~/.bash_profile 裡面，例如：</p>
<blockquote>
<pre>export PATH=~/Library/Android/sdk/platform-tools:~/Library/Android/sdk/tools:/usr/local/bin:${PATH}</pre>
</blockquote>
<p>上面指令加好之後，需要先把 Terminal 關掉再開啟，才能套用到 path 參數。</p>
<p>套用到 path 參數後，可以下指令 adb 看看能不能「直接」執行到 path 上的指令。</p>
<p>&nbsp;</p>
<p>3. 安裝 Node.js</p>
<p>先安裝 homebrew，指令：</p>
<blockquote>
<pre>/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"</pre>
</blockquote>
<p>詳全文：<a href="https://brew.sh/index_zh-tw.html">https://brew.sh/index_zh-tw.html</a></p>
<p>&nbsp;</p>
<p>安裝 Node:</p>
<blockquote>
<pre>brew install node</pre>
</blockquote>
<p>安裝 ant</p>
<blockquote>
<pre>brew install ant</pre>
</blockquote>
<p>&nbsp;</p>
<p>4. 用 npm 安裝 ios-sim 和 ios-deploy 兩個套件，</p>
<blockquote>
<pre>npm install -g ios-sim
npm install -g ios-deploy</pre>
</blockquote>
<p>&nbsp;</p>
<p>5. 用 npm 來安裝 Cordova：</p>
<blockquote>
<pre>sudo npm install -g cordova</pre>
</blockquote>
<p>附註：如果直接使用 npm 沒有 sudo 不會出錯的話，代表目前帳號的存取權限夠大，不夠大時請加 sudo 來執行 npm.</p>
<p>&nbsp;</p>
<p>6. 建立一個 Hello World 專案：</p>
<blockquote>
<pre>cordova create hello com.example.hello HelloWorld</pre>
</blockquote>
<p>&nbsp;</p>
<p>7. 進入 hello 目錄下</p>
<blockquote>
<pre>cd hello</pre>
</blockquote>
<p>&nbsp;</p>
<p>8. 加入了 ios 和 android平台：</p>
<blockquote>
<pre>cordova platform add ios
cordova platform add android</pre>
</blockquote>
<p>要移掉一個平台：</p>
<blockquote>
<pre>cordova platform remove ios</pre>
</blockquote>
<p>&nbsp;</p>
<p>9. 分別把 Android 和 iOS 的模擬器跑起來:</p>
<blockquote>
<pre>cordova emulate android
cordova emulate ios</pre>
</blockquote>
<p>&nbsp;</p>
<p>要知道安裝了那些外掛：</p>
<blockquote>
<pre>cordova plugin list</pre>
</blockquote>
<p>要移除外掛, you can simply do:</p>
<blockquote>
<pre>cordova plugin remove &lt;PLUGIN_NAME&gt;</pre>
</blockquote>
<p>For example:</p>
<blockquote>
<pre>cordova plugin remove org.apache.cordova.media</pre>
</blockquote>
<p>要新增外掛：</p>
<blockquote>
<pre>cordova plugin add airwatch-sdk-plugin</pre>
</blockquote>
<p>&nbsp;</p>
<p>要部署到 iOS:</p>
<p><a href="https://cordova.apache.org/docs/zh-cn/latest/guide/platforms/ios/index.html">https://cordova.apache.org/docs/zh-cn/latest/guide/platforms/ios/index.html</a></p>
<p>要部署的應用程式連接的 iOS 設備上：</p>
<div class="highlight">
<pre><code class="language-" data-lang="">    $ cordova run ios --device</code></pre>
<p>&nbsp;</p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2017/12/cordova-mac-helloworld/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
