<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8322614652561522170</id><updated>2026-09-26T07:07:26.639-07:00</updated><category term="iOS"/><category term="privacy"/><category term=".net"/><category term="windows"/><category term="C#"/><category term="UI"/><category term="UITableView"/><category term="exception"/><category term="iPhone"/><category term="permission"/><category term="wpf"/><category term="Date Format Patterns"/><category term="HH:mm:ss"/><category term="SSO"/><category term="UITableViewCell"/><category term="UITextField"/><category term="XAML"/><category term="XMLHttpRequest"/><category term="Xcode"/><category term="android"/><category term="apple"/><category term="apple script"/><category term="application state"/><category term="arm"/><category term="asynctask"/><category term="background"/><category term="bash"/><category term="block"/><category term="character encoding"/><category term="chinese"/><category term="depreciated"/><category term="iPad"/><category term="iPod touch"/><category term="intercept"/><category term="js"/><category term="keyboard"/><category term="payapl"/><category term="redirect Uri"/><category term="reload"/><category term="repeat horizontally"/><category term="reset"/><category term="route"/><category term="scroll to top"/><category term="simulator"/><category term="template"/><category term="terminate background"/><category term="thread"/><category term="timestring"/><category term="unicode words"/><category term="update"/><category term="vpn"/><category term="weibo"/><category term="woocommerce"/><category term="wordpress"/><category term="wrong offset"/><category term="yyyy-MM-dd"/><title type='text'>The way to be great programmer</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-2224272703358152445</id><published>2016-11-30T21:57:00.000-08:00</published><updated>2016-11-30T21:57:23.472-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="apple script"/><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="route"/><category scheme="http://www.blogger.com/atom/ns#" term="vpn"/><title type='text'>VPN for internal service</title><content type='html'>Have to setup VPN for internal service, using AWS as VPN server&lt;br /&gt;
---- &lt;br /&gt;
AWS VPN in 10 mins:&lt;br /&gt;
https://www.webdigi.co.uk/blog/2015/how-to-setup-your-own-private-secure-free-vpn-on-the-amazon-aws-cloud-in-10-minutes/&lt;br /&gt;
---&lt;br /&gt;
but I don&#39;t want all traffic go through VPN, I have to setup routes&lt;br /&gt;
using Apple script as below:&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;pre style=&quot;white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;&lt;code&gt;property version : &quot;2016-12-01&quot;
property theShellScript : &quot;#!/bin/sh
rm /etc/ppp/ip-up
sudo echo &#39;#!/bin/sh&#39; &amp;gt;&amp;gt; /etc/ppp/ip-up
sudo echo &#39;/sbin/route add -net &quot;destination.com&quot; -interface $1&#39; &amp;gt;&amp;gt; /etc/ppp/ip-up
sudo echo &#39;/sbin/route add -net google.com -interface $1&#39; &amp;gt;&amp;gt; /etc/ppp/ip-up
chmod 0755 /etc/ppp/ip-up
cat /etc/ppp/ip-up&quot;
do shell script theShellScript with administrator privileges
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
What it does is to put a ip-up file in /etc/ppp, when vpn is connect, the ip-up script will be executed, and route for&amp;nbsp; &lt;code&gt;&quot;destination.com&quot;&lt;/code&gt;  will be route through VPN</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/2224272703358152445/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2016/11/vpn-for-internal-service.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/2224272703358152445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/2224272703358152445'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2016/11/vpn-for-internal-service.html' title='VPN for internal service'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-5523923661771535216</id><published>2016-04-13T18:54:00.003-07:00</published><updated>2016-04-13T18:56:40.724-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="reload"/><category scheme="http://www.blogger.com/atom/ns#" term="UI"/><category scheme="http://www.blogger.com/atom/ns#" term="UITableView"/><category scheme="http://www.blogger.com/atom/ns#" term="UITableViewCell"/><category scheme="http://www.blogger.com/atom/ns#" term="update"/><title type='text'>Update UITableViewCell from itself</title><content type='html'>The code that can update the cell itself.
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;// update UI on main thread
dispatch_async(dispatch_get_main_queue(), ^{
    //set cell need update
    [self setNeedsUpdateConstraints];
    [self updateConstraintsIfNeeded];
    [self setNeedsLayout];
    [self layoutIfNeeded];
    //trying to get the tableview
    id view = [self superview];
    // different level of UITableView wrapping in different iOS version,
    // for more detail please see:
    // &lt;a href=&quot;http://stackoverflow.com/questions/15711645/how-to-get-uitableview-from-uitableviewcell&quot;&gt; stackoverflow &lt;/a&gt;
    while (view &amp;amp;&amp;amp; [view isKindOfClass:[UITableView class]] == NO) {
        view = [view superview];
    }
    
    if (view) {
        UITableView *tableView = (UITableView *)view;
        NSIndexPath *indexPath = [tableView indexPathForCell:self];
        if (indexPath) {
            [tableView reloadRowsAtIndexPaths:@[indexPath] 
                             withRowAnimation:UITableViewRowAnimationNone];
        }
    }
});
&lt;/code&gt;&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/5523923661771535216/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2016/04/update-uitableviewcell-from-itself.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/5523923661771535216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/5523923661771535216'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2016/04/update-uitableviewcell-from-itself.html' title='Update UITableViewCell from itself'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-3452499231425716591</id><published>2016-04-11T20:30:00.001-07:00</published><updated>2016-04-11T20:30:13.878-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="intercept"/><category scheme="http://www.blogger.com/atom/ns#" term="js"/><category scheme="http://www.blogger.com/atom/ns#" term="XMLHttpRequest"/><title type='text'>[JavaScript]Get XMLHttpRequest Traffic</title><content type='html'>&amp;nbsp;Case: finding network traffic of a website, can&#39;t see relevant in the Console-&amp;gt;network in Chrome, dig into code, it is XMLHttpRequest and not log in Console-&amp;gt;Network&lt;br /&gt;&lt;br /&gt;How: In console add hook into XMLHttpRequest&lt;br /&gt;
&lt;br /&gt;
Code: 
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;var rawOpen = XMLHttpRequest.prototype.open;&lt;br /&gt;&lt;br /&gt;XMLHttpRequest.prototype.open = function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!this._hooked) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;this._hooked = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;setupHook(this);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rawOpen.apply(this, arguments);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function setupHook(xhr) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function getter() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;console.log(&#39;get responseText&#39;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;delete xhr.responseText;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;var ret = xhr.responseText;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;setup();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;console.log(&#39;url : %s&#39;,xhr.responseURL);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;console.log(&#39;ret : %s&#39;,ret);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return ret;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function setter(str) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;console.log(&#39;set responseText: %s&#39;, str);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function setup() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;Object.defineProperty(xhr, &#39;responseText&#39;, {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;get: getter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;set: setter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;configurable: true&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;});&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; setup();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Source : &lt;a href=&quot;http://stackoverflow.com/questions/16959359/intercept-xmlhttprequest-and-modify-responsetext&quot;&gt;http://stackoverflow.com/questions/16959359/intercept-xmlhttprequest-and-modify-responsetext&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/3452499231425716591/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2016/04/javascriptget-xmlhttprequest-traffic.html#comment-form' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3452499231425716591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3452499231425716591'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2016/04/javascriptget-xmlhttprequest-traffic.html' title='[JavaScript]Get XMLHttpRequest Traffic'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-3474069779351371324</id><published>2016-04-04T20:36:00.002-07:00</published><updated>2016-04-04T20:36:55.252-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="keyboard"/><category scheme="http://www.blogger.com/atom/ns#" term="scroll to top"/><category scheme="http://www.blogger.com/atom/ns#" term="UITableView"/><category scheme="http://www.blogger.com/atom/ns#" term="UITextField"/><category scheme="http://www.blogger.com/atom/ns#" term="wrong offset"/><title type='text'>[iOS] UITableView scroll to top when typing in the textfield will scroll to a wrong location</title><content type='html'>My case is this:&lt;br /&gt;
&lt;br /&gt;
I have a static table, with hidden cell(height = 0), custom cell that will open keyboard, and a reset button(that will reload table and scroll to top)&lt;br /&gt;
&lt;br /&gt;
What is the problem:&lt;br /&gt;
&lt;br /&gt;
Scroll to top will go to invalid offset.&lt;br /&gt;
&lt;br /&gt;
How to regenerate:&lt;br /&gt;
&lt;br /&gt;
type in the keyboard, reset(which scroll to top and reload the keyboard) and there will be space between my top cell and top of table (just like hidden cell consumed some space)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
At first I thought it is the hidden cell problem, but it turns out to be problem on [tableView reloadData]&lt;br /&gt;
&lt;br /&gt;
**[tableView reloadData] will interrupt scrolling, so make sure you call [tableView setContentOffset:] or [tableView scrollToRowAtIndexPath:] after all reload is done.&lt;br /&gt;
&lt;br /&gt;
Reference: &lt;a href=&quot;http://stackoverflow.com/questions/16645858/scroll-table-view-top-when-selecting-an-textfield&quot;&gt;stackoverflow&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/3474069779351371324/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2016/04/ios-uitableview-scroll-to-top-when.html#comment-form' title='7 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3474069779351371324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3474069779351371324'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2016/04/ios-uitableview-scroll-to-top-when.html' title='[iOS] UITableView scroll to top when typing in the textfield will scroll to a wrong location'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-274833315375227064</id><published>2015-11-17T19:09:00.000-08:00</published><updated>2017-01-05T19:10:08.570-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="character encoding"/><category scheme="http://www.blogger.com/atom/ns#" term="chinese"/><category scheme="http://www.blogger.com/atom/ns#" term="payapl"/><category scheme="http://www.blogger.com/atom/ns#" term="unicode words"/><category scheme="http://www.blogger.com/atom/ns#" term="woocommerce"/><category scheme="http://www.blogger.com/atom/ns#" term="wordpress"/><title type='text'>Paypal say &quot;Data does not match input character set or default encoding&quot; when WooCommerce Wordpress Checkout with Chinese words</title><content type='html'>Recently I am playing with Wordpress and WooCommerce shopping Cart plugin for wordpress to setup a simple E-commerce website, while I am using a plugin to add some extra info to my product ( &lt;a href=&quot;https://wordpress.org/plugins/woocommerce-product-addon/&quot;&gt;WooCommerce Extra Fields&lt;/a&gt; ) with some chinese character, it randomly give me &quot;Data does not match input character set or default encoding&quot; during checkout.
&lt;br /&gt;
&lt;br /&gt;
After some digging on the network call, I found that the product name is in the Paypal link, and the chinese word is trimmed and become weird character.

&lt;br /&gt;
&lt;br /&gt;
I found the trim function &lt;a href=&quot;https://docs.woothemes.com/wc-apidocs/function-wc_trim_string.html&quot;&gt;wc_trim_string&lt;/a&gt; is the one to be blamed, and it is using php &lt;a href=&quot;http://php.net/manual/en/function.substr.php&quot;&gt;substr&lt;/a&gt; function.

&lt;br /&gt;
&lt;br /&gt;
The original wc_trim_string function in &quot;woocommerce/include/wc-formatting-functions.php&quot; contains the line:
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
 $string = substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
i just replaced it with &lt;a href=&quot;http://php.net/manual/en/function.mb-substr.php&quot;&gt;mb_substr&lt;/a&gt; and everything works like charm again.
End result will look like:

&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
 $string = mb_substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The reason is that substr function just trim without handling multiple-byte unicode character, and mb_substr is multi-byte safe.

&lt;br /&gt;
&lt;br /&gt;
This workaround should works on other multibyte/unicode character.


&lt;br /&gt;
&lt;br /&gt;
Note: Version of my WooCommerce is v2.4.8</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/274833315375227064/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2017/01/paypal-say-data-does-not-match-input.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/274833315375227064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/274833315375227064'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2017/01/paypal-say-data-does-not-match-input.html' title='Paypal say &quot;Data does not match input character set or default encoding&quot; when WooCommerce Wordpress Checkout with Chinese words'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-4063476020735946770</id><published>2013-03-17T23:26:00.000-07:00</published><updated>2013-03-17T23:26:02.179-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="android"/><category scheme="http://www.blogger.com/atom/ns#" term="asynctask"/><category scheme="http://www.blogger.com/atom/ns#" term="block"/><category scheme="http://www.blogger.com/atom/ns#" term="thread"/><title type='text'>[Android] AsyncTask blocking</title><content type='html'>In different Android version, there is different handling on AsyncTask, some are in single thread, processed one by one, some are multi-threaded and processed at the same time.&lt;br /&gt;
&lt;br /&gt;
1.0-1.5(API 1-3) single thread.&lt;br /&gt;
1.6-2.3.3 (API4-10) multi thread.&lt;br /&gt;
3.0+ (API 11 or up) single thread.&lt;br /&gt;
&lt;br /&gt;
but if you want to have AsyncTask run on seperate thread, you can call 
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);&lt;/code&gt;&lt;/pre&gt;
instead of&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;    task.execute(params);&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
then the task will run on seperate thread, and not blocked by other threads.
</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/4063476020735946770/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2013/03/android-asynctask-blocking.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/4063476020735946770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/4063476020735946770'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2013/03/android-asynctask-blocking.html' title='[Android] AsyncTask blocking'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-5150664835333434233</id><published>2012-11-16T21:19:00.000-08:00</published><updated>2012-11-16T21:19:54.461-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="background"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="repeat horizontally"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><category scheme="http://www.blogger.com/atom/ns#" term="wpf"/><title type='text'>[WPF]Background dynamic fill with one direction</title><content type='html'>I have a very long and thin image, and I want to use it as a background image in WPF application, which the image should repeat horizontally.&lt;br /&gt;
My first code insight is from&lt;br /&gt;
&lt;blockquote&gt;
&lt;a href=&quot;http://stackoverflow.com/questions/1782979/wpf-how-do-i-create-a-background-that-repeats-horizontally-without-scalling&quot;&gt;WPF: How do i create a background that repeats horizontally without scalling?&lt;/a&gt;
&lt;/blockquote&gt;
But, it fails to repeats properly, the reason is that ViewportUnits=&quot;Absolute&quot;,
so it actually stretch my image to very large. Which is kind of hardcode.&lt;br /&gt;
&lt;br /&gt;
Then I saw this reference &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.media.tilebrush.viewport.aspx&quot;&gt;TileBrush.Viewport Property&lt;/a&gt;
&lt;br /&gt;
So I use this this code to create the background brush instead
&lt;br /&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;  &amp;lt;imagebrush imagesource=&quot;/Resources/Image/pattern.png&quot; 
            tilemode=&quot;FlipY&quot; viewport=&quot;0,0,0.033,1&quot; 
            viewportunits=&quot;RelativeToBoundingBox&quot;
            x:key=&quot;BackGroundBrush&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;

Which 0.033:1 is the width:height ratio of my background. With this brush, the image will be stretch to suitable height.&lt;br /&gt;
&lt;br /&gt;
For repeat horizontally, just change tilemode to FlipX and viewport to &quot;0,0,1,x&quot; where 1:x is the ratio.&lt;br /&gt;
&lt;br /&gt;
p.s. this method is a improved version of the stackoverflow solution on the way that it can show the whole image, but the drawback is the image might be stretched for a little.
And seems there is no simple way to do this without binding.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/5150664835333434233/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/11/wpfbackground-dynamic-fill-with-one.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/5150664835333434233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/5150664835333434233'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/11/wpfbackground-dynamic-fill-with-one.html' title='[WPF]Background dynamic fill with one direction'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-7030209639691950299</id><published>2012-10-21T20:48:00.000-07:00</published><updated>2012-10-31T03:17:33.791-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="redirect Uri"/><category scheme="http://www.blogger.com/atom/ns#" term="SSO"/><category scheme="http://www.blogger.com/atom/ns#" term="weibo"/><title type='text'>Why Weibo SSO sdk don&#39;t jump back to my iOS app</title><content type='html'>This question is for those didn&#39;t watch the documentation of the SSO-sdk(me as an example).&lt;br/&gt;
&lt;br/&gt;
The callback url is not set in the web. It should be placed when you initiate the SinaWeibo instance. It is provided 2 init method and they are:
&lt;pre&gt;&lt;code&gt;-(id) initWithAppKey:(NSString*)_appKey 
           appSecret:(NSString *)_appSecrect 
      appRedirectURI:(NSString *) _appRedirectURI
         andDelegate:(id&lt;SinaWeiboDelegate&gt;)_delegate &lt;/code&gt;&lt;/pre&gt;
and
&lt;pre&gt;&lt;code&gt;- (id)initWithAppKey:(NSString *)_appKey 
           appSecret:(NSString *)_appSecrect 
      appRedirectURI:(NSString *) _appRedirectURI
   ssoCallbackScheme:(NSString *)_ssoCallbackScheme
         andDelegate:(id&lt;SinaWeiboDelegate&gt;)_delegate
&lt;/code&gt;&lt;/pre&gt;
We should use the latter one and put the callback Uri as ssoCallbackScheme, then everything will be work fine.</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/7030209639691950299/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/why-weibo-sso-sdk-dont-jump-back-to-my.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/7030209639691950299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/7030209639691950299'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/why-weibo-sso-sdk-dont-jump-back-to-my.html' title='Why Weibo SSO sdk don&#39;t jump back to my iOS app'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-2008476557099631574</id><published>2012-10-18T02:30:00.001-07:00</published><updated>2012-10-18T02:30:43.060-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Date Format Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="HH:mm:ss"/><category scheme="http://www.blogger.com/atom/ns#" term="timestring"/><category scheme="http://www.blogger.com/atom/ns#" term="yyyy-MM-dd"/><title type='text'>Time to String? Date Format Patterns?</title><content type='html'>To convert time to string, we always use formats like &quot;yyyy-MM-dd HH:mm:ss&quot;, but sometimes we want something more like &quot;18 Oct 2012&quot; or &quot;Wed 12:34:56&quot;, then the reference page can help you. &lt;br/&gt;
&lt;blockquote&gt;&lt;a href=&quot;http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns&quot;&gt;Date Format Patterns&lt;/a&gt;&lt;/blockquote&gt;
&lt;br/&gt;
With the table in the page, you should be good enough to do more tricks on date formats.

</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/2008476557099631574/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/time-to-string-date-format-patterns.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/2008476557099631574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/2008476557099631574'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/time-to-string-date-format-patterns.html' title='Time to String? Date Format Patterns?'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-3407492005534221145</id><published>2012-10-15T22:49:00.002-07:00</published><updated>2012-10-15T22:49:53.110-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="privacy"/><category scheme="http://www.blogger.com/atom/ns#" term="simulator"/><title type='text'>[iOS] Why no privacy alerts in simulator?</title><content type='html'>This is not a bug. This is the restriction on simulator.&lt;br /&gt;
From the iOS6.0 release note, we seen that apple doesn&#39;t the privacy alerts in simulator.&lt;br /&gt;
&lt;blockquote&gt;
&lt;h3&gt;
Simulator&lt;/h3&gt;
&lt;ul class=&quot;ul&quot;&gt;
&lt;li class=&quot;li&quot;&gt;No privacy alerts are displayed in iOS Simulator for apps that access Photos, Contacts, Calendar, and Reminders. &lt;/li&gt;
&lt;li class=&quot;li&quot;&gt;For
 this release, iOS Simulator does not support testing In-App Purchase. 
Please use a device to test your apps that use this feature. &lt;/li&gt;
&lt;li class=&quot;li&quot;&gt;When attempting to play an MP3 sound in Simulator, you will hear a popping sound instead. &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
Source:&lt;a href=&quot;https://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html#//apple_ref/doc/uid/TP40012166-CH1-SW12&quot;&gt;iOS6.0 release note&lt;/a&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/3407492005534221145/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/ios-why-no-privacy-alerts-in-simulator.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3407492005534221145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3407492005534221145'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/ios-why-no-privacy-alerts-in-simulator.html' title='[iOS] Why no privacy alerts in simulator?'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-3418238003472646398</id><published>2012-10-15T22:43:00.001-07:00</published><updated>2012-10-15T22:43:24.147-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><category scheme="http://www.blogger.com/atom/ns#" term="privacy"/><category scheme="http://www.blogger.com/atom/ns#" term="reset"/><title type='text'>Reset iPhone Privacy</title><content type='html'>To clear/reset iPhone Privacy Settings like contacts and location services, you can go to Settings and follow the routine:&lt;br /&gt;
&lt;blockquote&gt;
Settings -&amp;gt; General -&amp;gt; Reset -&amp;gt; Reset Privacy and Location&lt;/blockquote&gt;&lt;br /&gt;
Which is useful for developer, as the privacy prompt only prompt once if you never reset.
</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/3418238003472646398/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/reset-iphone-privacy.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3418238003472646398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3418238003472646398'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/reset-iphone-privacy.html' title='Reset iPhone Privacy'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-8773046597860764720</id><published>2012-10-14T22:59:00.000-07:00</published><updated>2012-10-14T22:59:09.390-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="permission"/><category scheme="http://www.blogger.com/atom/ns#" term="privacy"/><title type='text'>Toggling Privacy settings in iOS6 will kill the app</title><content type='html'>If you played with Location Services in iPhone, you knows that after you changed the location setting in iPhone Settings, you are able to get the change and update your application. While Contact(AddressBook) and Location Services are both packed in Privacy Setting, you would expect there is similar behaviour on Contact.&lt;br/&gt;
&lt;br/&gt;
Sadly, its not true. After you changed the setting of contact, your app will receive a SIGKILL signal and stop.&lt;br/&gt;
&lt;br/&gt;
Source:&lt;a href=&quot;http://stackoverflow.com/questions/12522574/toggling-privacy-settings-will-kill-the-app/12668187#12668187&quot;&gt;StackOverflow&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/8773046597860764720/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/toggling-privacy-settings-in-ios6-will.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/8773046597860764720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/8773046597860764720'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/toggling-privacy-settings-in-ios6-will.html' title='Toggling Privacy settings in iOS6 will kill the app'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-8393418749843387422</id><published>2012-10-11T22:16:00.001-07:00</published><updated>2012-10-11T22:18:47.948-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="apple"/><category scheme="http://www.blogger.com/atom/ns#" term="arm"/><category scheme="http://www.blogger.com/atom/ns#" term="iPad"/><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><category scheme="http://www.blogger.com/atom/ns#" term="iPod touch"/><category scheme="http://www.blogger.com/atom/ns#" term="Xcode"/><title type='text'>Apple iDevice architecture</title><content type='html'>Since XCode4.5, apple have drop support to ARM architecture of ARMv6, and set the minimum device version to 4.3, which burden developers that need to support older version.&lt;br /&gt;
&lt;br /&gt;
To understand how it affect developers, one should understand there are 2 fields they need to handle with, they are:&lt;br /&gt;
&lt;blockquote&gt;
1. ARM Architecture&lt;br /&gt;
2. iOS Deployment Target&lt;/blockquote&gt;
&lt;br /&gt;
to know more about architecture, please visit &lt;a href=&quot;http://en.wikipedia.org/wiki/Instruction_set&quot;&gt;instruction set architecture&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
In this article, we mainly focus on the architecture of different apple device.&lt;br /&gt;
&lt;br /&gt;
The first question you may want to ask is, what iDevice is using ARMv6 architecture? The answer is simple, For iPhone, it is &lt;a href=&quot;http://en.wikipedia.org/wiki/IPhone_(original)&quot;&gt;iPhone(original)&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/IPhone_3G&quot;&gt;iPhone 3G&lt;/a&gt;. For iPod Touch, it is only &lt;a href=&quot;http://en.wikipedia.org/wiki/IPod_Touch&quot;&gt;1st generation&lt;/a&gt;.&lt;br /&gt;
For iPad, none of them are using ARMv6.

Here is more detail:&lt;br /&gt;
&lt;br /&gt;
iPhone:
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;CPU Core&lt;/th&gt;
&lt;th&gt;ARM architecture&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPhone&lt;/th&gt;
&lt;th rowspan=&quot;2&quot;&gt;620 MHz (underclocked to 412 MHz)
ARM 1176JZ(F)-S&lt;/th&gt;
&lt;th rowspan=&quot;2&quot;&gt;ARMv6&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;iPhone 3G&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPhone 3GS&lt;/th&gt;
&lt;th&gt;833 MHz (underclocked to 600 MHz)
ARM Cortex-A8&lt;/th&gt;
&lt;th rowspan=&quot;3&quot;&gt;ARMv7&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPhone 4&lt;/th&gt;
&lt;th&gt;1 GHz (underclocked to 800 MHz)
Apple A4&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPhone 4S&lt;/th&gt;
&lt;th&gt;1 GHz (underclocked to 800 MHz)
Dual-core Apple A5&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPhone 5&lt;/th&gt;
&lt;th&gt;Apple A6&lt;/th&gt;
&lt;th&gt;ARMv7s&lt;/th&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
iPod Touch:
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;CPU Core&lt;/th&gt;
&lt;th&gt;ARM architecture&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;1st generation&lt;/th&gt;
&lt;th&gt;620 MHz (underclocked to 412 MHz, originally 400 MHz)
ARM 1176JZ(F)-S&lt;/th&gt;
&lt;th&gt;ARMv6&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;2nd generation&lt;/th&gt;
&lt;th&gt;620 MHz (underclocked to 533 MHz)
ARM 1176JZ(F)-S&lt;/th&gt;
&lt;th rowspan=&quot;4&quot;&gt;ARMv7&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;3rd generation&lt;/th&gt;
&lt;th&gt;833 MHz (underclocked to 600 MHz)
ARM Cortex-A8 core&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;4th generation&lt;/th&gt;
&lt;th&gt;1 GHz (underclocked to 800 MHz)
ARM Cortex-A8&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;5th generation&lt;/th&gt;
&lt;th&gt;ARM Cortex-A9&lt;/th&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
iPad:
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;CPU Core&lt;/th&gt;
&lt;th&gt;ARM architecture&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPad (original)&lt;/th&gt;
&lt;th&gt;1 GHz ARM Cortex-A8&lt;/th&gt;
&lt;th rowspan=&quot;3&quot;&gt;ARMv7&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPad 2&lt;/th&gt;
&lt;th&gt;1 GHz dual-core ARM Cortex-A9&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;iPad (3rd generation)&lt;/th&gt;
&lt;th&gt;1 GHz dual-core ARM Cortex-A9&lt;/th&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/8393418749843387422/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/apple-idevice-architecture.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/8393418749843387422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/8393418749843387422'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/apple-idevice-architecture.html' title='Apple iDevice architecture'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-1493041112857139309</id><published>2012-10-08T20:53:00.001-07:00</published><updated>2012-10-08T20:53:23.601-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="exception"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="permission"/><category scheme="http://www.blogger.com/atom/ns#" term="privacy"/><title type='text'>iOS6 permissions [Contacts]</title><content type='html'>On iOS6, apple introduce new privacy control, user can control the accessment of contact and calender by each app.

So, in the code side, you need to add some way to request the permission.

In iOS5 or before, we can always call 
&lt;br /&gt;
&lt;blockquote&gt;
ABAddressBookRef addressBook = ABAddressBookCreate();&lt;/blockquote&gt;
to get the addressbook without any problem,

but in iOS6, if you don&#39;t have permission, this call will just return empty pointer.

That why we need to change the method to get ABAddressBookRef.

&lt;br /&gt;
&lt;blockquote&gt;
&lt;br /&gt;
__block BOOL accessGranted = NO;&lt;br /&gt;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we&#39;re on iOS 6&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; dispatch_semaphore_t sema = dispatch_semaphore_create(0);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; accessGranted = granted;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dispatch_semaphore_signal(sema);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; dispatch_release(sema);&amp;nbsp;&amp;nbsp; &lt;br /&gt;
}&lt;br /&gt;
else { // we&#39;re on iOS 5 or older&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; accessGranted = YES;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (accessGranted) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do whatever you want here.&lt;br /&gt;
}&lt;/blockquote&gt;
In the code,semaphore is used for blocking until response, while  ABAddressBookRequestAccessWithCompletion will ask for permission if the app didn&#39;t ask before. Otherwise it will just follow the settings in Settings-Privacy-Contact.</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/1493041112857139309/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/ios6-permissions-contacts.html#comment-form' title='13 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/1493041112857139309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/1493041112857139309'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/10/ios6-permissions-contacts.html' title='iOS6 permissions [Contacts]'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-3689276228971262689</id><published>2012-05-10T19:44:00.000-07:00</published><updated>2012-05-10T19:44:01.058-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="depreciated"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><title type='text'>[Windows] Depreciated in C#</title><content type='html'>To set a function in .net as depreciated, we can use code like this&lt;br/&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;

        [Obsolete(&quot;Reason of depreciate.&quot;)]
        public void Your_Function(int parameters)
        {
            Your_Code_Here;
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;be/&gt;

After that, when you reference this function, it will shows as depreciated, and will have a warning saying your call is obsolete.</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/3689276228971262689/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/05/windows-depreciated-in-c.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3689276228971262689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/3689276228971262689'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/05/windows-depreciated-in-c.html' title='[Windows] Depreciated in C#'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-8098148270284715103</id><published>2012-05-04T21:50:00.001-07:00</published><updated>2012-05-04T21:50:48.165-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="template"/><category scheme="http://www.blogger.com/atom/ns#" term="UI"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><category scheme="http://www.blogger.com/atom/ns#" term="wpf"/><category scheme="http://www.blogger.com/atom/ns#" term="XAML"/><title type='text'>[Windows] Basic WPF UI template</title><content type='html'>When you creating a UI for your application, usually you will make several UI element of same type, it is kind of annoying if you need to copy and paste all attributes to make those object looks the same. So in XAML programming in WPF, you can define a template for your controls.&lt;br /&gt;
&lt;br /&gt;
Code snapshot:&lt;br /&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;UserControl&amp;gt;
    &amp;lt;UserControl.Resources&amp;gt;
        &amp;lt;Style x:Key=&quot;BaseBtn&quot; TargetType=&quot;Button&quot;&amp;gt;
            &amp;lt;Setter Property=&quot;Width&quot; Value=&quot;80px&quot;/&amp;gt;
            &amp;lt;Setter Property=&quot;Height&quot; Value=&quot;80px&quot;/&amp;gt;
        &amp;lt;/Style&amp;gt;
        &amp;lt;Style x:Key=&quot;BottomRightBtn&quot; BasedOn=&quot;{StaticResource BaseBtn}&quot; 
                TargetType=&quot;Button&quot;&amp;gt;
            &amp;lt;Setter Property=&quot;HorizontalAlignment&quot; Value=&quot;Right&quot;/&amp;gt;
            &amp;lt;Setter Property=&quot;VerticalAlignment&quot; Value=&quot;Bottom&quot;/&amp;gt;
            &amp;lt;Setter Property=&quot;Margin&quot; Value=&quot;10&quot;/&amp;gt;
        &amp;lt;/Style&amp;gt;
        &amp;lt;Style x:Key=&quot;BottomLeftBtn&quot; BasedOn=&quot;{StaticResource BaseBtn}&quot;
                TargetType=&quot;Button&quot;&amp;gt;
            &amp;lt;Setter Property=&quot;HorizontalAlignment&quot; Value=&quot;Left&quot;/&amp;gt;
            &amp;lt;Setter Property=&quot;VerticalAlignment&quot; Value=&quot;Bottom&quot;/&amp;gt;
            &amp;lt;Setter Property=&quot;Margin&quot; Value=&quot;10&quot;/&amp;gt;
        &amp;lt;/Style&amp;gt;
    &amp;lt;/UserControl.Resources&amp;gt; 
    &amp;lt;Grid&amp;gt;
        &amp;lt;Button Content=&quot;BaseBtn&quot; Style=&quot;{StaticResource BaseBtn}&quot;/&amp;gt;
        &amp;lt;Button Content=&quot;BottomLeftBtn&quot;
                Style=&quot;{StaticResource BottomLeftBtn}&quot;/&amp;gt;
        &amp;lt;Button Content=&quot;BottomRightBtn&quot;
                Style=&quot;{StaticResource BottomRightBtn}&quot;/&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
&lt;code&gt;UserControl.Resources&lt;/code&gt; is a nice place to put all your styles.&lt;br /&gt;
Note that you need to specify the &lt;code&gt;TargetType&lt;/code&gt; in style tag. So your style can be used on this type only.&lt;br /&gt;
Each &lt;code&gt;Setter&lt;/code&gt; define a single property like width and height, which should also exist in the target type.&lt;br /&gt;
To use the style, just use something like &lt;code&gt;Style=&quot;{StaticResource ResourceKey}&quot; &lt;/code&gt;to reference them.&lt;br /&gt;
That how you do simple sytle in WPF XAML, probably will save you some time.</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/8098148270284715103/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/05/windows-basic-wpf-ui-template.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/8098148270284715103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/8098148270284715103'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/05/windows-basic-wpf-ui-template.html' title='[Windows] Basic WPF UI template'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-589908530084571755</id><published>2012-04-29T22:05:00.000-07:00</published><updated>2012-04-29T22:05:27.795-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="exception"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><title type='text'>[iOS] Exception catching</title><content type='html'>Exception catching is essential in developing application in .net framework and java.&lt;br /&gt;
While in Objective-C, it is much less powerful and shouldn&#39;t rely on it, as usually it just crash and didn&#39;t catch anything. Yet, it is still a plus if you really catch something.&lt;br /&gt;
&lt;br /&gt;
Usage is really simple&lt;br /&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;@try
{
    Function_You_Want_To_Catch_Exception;
}
@catch (NSException* exception)
{
   Do_Thing_After_Exception_Caught;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;br /&gt;&lt;br /&gt;
One example is to put it in &lt;code&gt;main.m&lt;/code&gt;, in order to catch any uncaught exception.&lt;br /&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = -1;
    @try {
        retVal = UIApplicationMain(argc, argv, nil, nil);
    }
    @catch (NSException* exception) {
        NSLog(@&quot;Uncaught exception: %@&quot;, exception.description);
        NSLog(@&quot;Stack trace: %@&quot;, [exception callStackSymbols]);
    }
    [pool release];
    return retVal;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
which shows how to catch all uncatched exception in the app.&lt;br/&gt;
&lt;br/&gt;
Another usage is when you like &quot;exception programming&quot;, you can raise your own exception, by using
&lt;a href=&quot;http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSException_Class/Reference/Reference.html#//apple_ref/occ/clm/NSException/raise:format:&quot;&gt;[NSException raise:format:]&lt;/a&gt; and catch it with above code.&lt;br/&gt;
Example:&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;
[NSException raise:NSInvalidArgumentException format:@&quot;Foo must not be nil&quot;];
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;&lt;br/&gt;
There are several exception name already defined by apple &lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Constants/Reference/reference.html#//apple_ref/doc/uid/TP40003793-CH3g-BAJJDIDC&quot;&gt;here&lt;/a&gt;. but if you want to use your own, put a NSString there is fine.</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/589908530084571755/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/04/ios-exception-catching.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/589908530084571755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/589908530084571755'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/04/ios-exception-catching.html' title='[iOS] Exception catching'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8322614652561522170.post-5797256296281973351</id><published>2012-04-29T21:00:00.000-07:00</published><updated>2012-04-29T21:01:45.486-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="application state"/><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="terminate background"/><title type='text'>[iOS] Catch application end</title><content type='html'>Sometime we always want to catch the application terminate in mobile platform.&lt;br /&gt;
&lt;br /&gt;
In iDevice, we can use&lt;br /&gt;
&lt;div style=&quot;color: #674ea7;&quot;&gt;
&amp;nbsp;&lt;code&gt;- (void)applicationWillTerminate:(UIApplication *)application
&lt;/code&gt;&lt;/div&gt;
to catch the terminate action.&lt;br /&gt;
&lt;br /&gt;
But since iOS 4.0, application will goes to background instead of being killed when you press the home button.&lt;br /&gt;
If you are doing so, &lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;color: #674ea7;&quot;&gt;
&lt;code&gt;- (void)applicationWillTerminate:(UIApplication *)application&lt;/code&gt;&amp;nbsp;&lt;/div&gt;
might not be called.&lt;br /&gt;
&lt;br /&gt;
From apple developer&#39;s guide,&lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/applicationDidEnterBackground:&quot;&gt;UIApplicationDelegate Protocol Reference&lt;/a&gt;&amp;nbsp; &lt;br /&gt;
&lt;div style=&quot;color: #674ea7;&quot;&gt;
&lt;code&gt;- (void)applicationDidEnterBackground:(UIApplication *)application&lt;/code&gt;&amp;nbsp;&lt;/div&gt;
will be called instead.&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
When you goes to background, and kill the app bu double click the home button and click the red cross, &lt;br /&gt;
&lt;div style=&quot;color: #674ea7;&quot;&gt;
&amp;nbsp;&lt;code&gt;- (void)applicationWillTerminate:(UIApplication *)application&amp;nbsp;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
will still being called. But if it died naturally, then it won&#39;t be called.</content><link rel='replies' type='application/atom+xml' href='http://programmerjoe.blogspot.com/feeds/5797256296281973351/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://programmerjoe.blogspot.com/2012/04/ios-catch-application-end.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/5797256296281973351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8322614652561522170/posts/default/5797256296281973351'/><link rel='alternate' type='text/html' href='http://programmerjoe.blogspot.com/2012/04/ios-catch-application-end.html' title='[iOS] Catch application end'/><author><name>Josephus</name><uri>http://www.blogger.com/profile/00424732751250131163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>