網頁

2013年12月22日 星期日

HTML學習筆記-常用的特殊符號

老是每次都忘掉又要重新找,在這記一下別人做好的吧

符號說明編碼符號說明編碼符號說明編碼
雙引號"×乘號×向左箭頭←
&AND符號&÷除號÷向上箭頭↑
<小於符號&lt;±正負符號&plusmn;向右箭頭&rarr;
>大於符號&gt;function符號&fnof;向下箭頭&darr;
 空格&nbsp;根號&radic;雙向箭頭&harr;
倒問號&iquest;無限大符號&infin;雙線向左箭頭&lArr;
«雙左箭頭&laquo;角度符號&ang;雙線向上箭頭&uArr;
»雙右箭頭&raquo;微積分符號&int;雙線向右箭頭&rArr;
左單引號&lsquo;°度數符號&deg;雙線向下箭頭&dArr;
右單引號&rsquo;不等於符號&ne;雙線雙向箭頭&hArr;
左雙引號&ldquo;相等符號&equiv;黑桃符號&spades;
右雙引號&rdquo;小於等於符號&le;梅花符號&clubs;
段落符號&para;大於等於符號&ge;紅心符號&hearts;
§章節符號&sect;垂直符號&perp;方塊符號&diams;
©版權所有符號&copy;二分之一符號&frac12;αAlpha符號&alpha;
註冊商標符號&reg;四分之一符號&frac14;βBata符號&beta;
商標符號&trade;四分之三符號&frac34;γGamma符號&gamma;
歐元符號&euro;百分符號&permil;ΔDelta符號&Delta;
¢美分符號&cent;所以符號&there4;θTheta符號&theta;
£英鎊符號&pound;π圓周率符號&pi;λLambda符號&lambda;
¥日圓符號&yen;¹註解1符號&sup1;ΣSigma符號&Sigma;
&hellip;²註解2符號、平方&sup2;τTau符號&tau;
 &oplus;³註解3符號、立方&sup3;ωOmega符號&omega;
倒三角型符號&nabla;ENTER符號&crarr;ΩOmega符號、歐姆符號&Omega;


參考網址:
HTML常用的特殊符號

2013年12月19日 星期四

Ant學習筆記-javac compiler時的encoding error

在windows上用ant做compiler時,發現一直有以下的問題
compile:
    [javac] C:\apache-tomcat\current_source\src\com\controller\Controller.java:19: warning: unmappable character for encoding MS950
    [javac]  * 作業??: ?�司?��?

後來才發現在javac中要多個encoding
<javac encoding="UTF-8" src=... />
一直以來我都是用mac及linux在開發,即使mac預設用big5,使用ant時也不用設定這個,windows還真是神一般的系統

參考網址:
Ant encoding problem on Windows - UTF-8 files but spits garbage on diacritics

2013年11月26日 星期二

Tomcat筆記- Error: The web application [/web] appears to have started a thread named [Thread-2] but has failed to stop it. This is very likely to create a memory leak.

紀錄一下。

昨天弄了個舊web site放上tomcat,卻一直出現底下訊息,無法成功執行

The web application [/web] appears to have started a thread named [Thread-2] but has failed to stop it. This is very likely to create a memory leak.

查了半天,我認為是跟class有關,卻發現都在討論jdbc,後來查到server.xml及context.xml少放了幾個jndi的設定。

這真是個讓人困惑的log!

參考網址:

2013年11月22日 星期五

Eclipse - 安裝Remote System Explorer及使用

需求:

  • 在local端能使用eclipse開發的同時,能直接就放上Server端,直接在Server端compiler或使用

安裝(參考https://bugs.eclipse.org/bugs/attachment.cgi?id=110113):

  • 打開Eclipse
  • 按Help -> "Software Updates"
  • 按"Add Site,然後打入http://eclipse-incub.sourceforge.net/updates-soc/rse-sync/,再按ok
  • 按install
我選擇的是用Export,做法如下:
  • 先import或create proejct
  • 轉移到Remote System Explorer view
  • New Connection 選 ssh only
  • 填入host name、connection name(帳號),必要時寫description,按Finish
  • 登入後,找到project要放置的目錄按右鍵,選Export From project
  • 點選要export的project,勾選"Save the settings of this export in the workspace",寫入個檔案名字,按Finish
  • 轉到Team Synchronizing,將要上傳的檔案都put all,等待上傳完即可

之後就直接對著存好的rexpfd檔按右鍵,選"Open Remote file Exporter",再按finish就自動同步,之後改什麼檔案就再自行put即可,會只列出不一樣的檔案

缺點是每次開Ecplise都得重新同步,有時還蠻久的

參考網址:
How to synchronize files over FTP with Eclipse RSE?
https://bugs.eclipse.org/bugs/attachment.cgi?id=110113
http://www.chrisdanford.com/blog/2010/05/19/edit-files-directly-over-sftp-in-eclipse-remote-system-explorer/
Eclipse with Aptana plugin and SFTP support, a free website editor

Wordpress開發筆記-設定rewrite及htaccess

每次弄新的wordpress總會忘掉要做rewrite及htaccess,在這邊記一下

Apach config設定,vim /etc/httpd/conf/httpd.conf,然後加入
<Directory "{wordpress的路徑}">
AllowOverride All
</Directory>
restart apache server
/sbin/service httpd restart


至{wordpress的路徑}加入.htaccess
vim .htaccess,加入
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /{wordpress在www底下的路徑名}
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /{wordpress在www底下的路徑名}/index.php [L]
</IfModule>

參考網址:
htaccess
解决CentOS下.htaccess不起作用


2013年11月10日 星期日

Tomcat筆記-設定錯誤頁

有時希望在使用時別讓使用者看到Exception一類令人不懂的東西,這時就得將他們導向設定好的page,例如發生404時,導向網頁沒找到的訊息頁,tomcat的設定很容易,只要在project的web.xml中,servlet的設定後或檔案最後加入以下的設定,404.html放在WebContent下即可

<error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
</error-page>

這樣重開機就好。

參考網址:
[JSP]替換Tomcat的Error Page
防止駭客偷你的信箱網址
用 mailto 寄信
Status codes

2013年11月3日 星期日

JSTL學習筆記-jslt中強迫int或bigInteger轉成string

使用jslt時發現個狀況,記錄要傳到jsp的值用Map<String,String> results存放,key的值是id轉的,原型態是BigInteger,直接在jsp上用${ results[id] },會發生找不到值的問題,這時要強迫他自動轉型,如下述方式

<c:set var="id_val">${ id }</c:set>
${ results[id_val] }

會將其轉成string


參考網址:
JSTL Core <fmt:parseNumber> Tag

2013年10月22日 星期二

Javascript學習筆記-取代所有相關字串

想取代整個字串中所有特定字,但javascript沒有支援,找了下看到用regular expression方式也行,都忘了有這方法,做下紀錄

ex : replaceAll 小數點
var s1 = "A.B.C";
alert(s1.replace(/\./g,"_")); // "A_B_C"

參考網址:
[javascript] Javascript 的 replaceAll

2013年10月4日 星期五

jQuery開發筆記-jQuery Validate及ie 7的相容問題

需求
  1. 表單填資料,表單所在頁面是html,所以只能用javascript
  2. 送出要檢查必填及勾選個資使用同意
  3. 資料轉成mail寄出
  4. 相容到IE 7
需求是很簡單,但若只能用javascript,相容到IE 7就是個大問題,我檢查資料用的是jquery validate這個plugin,似乎也加重這問題,要比較後面的版本才相容,但jquery越後面的版本就越是放棄相容舊的IE,最後是總結如下:
  1. 使用jQuery 1.6.1
  2. 使用jQuery validate 1.8.1(在這jquery 1.8.1 download可以下載)
jQuery validate 1.8.1在選擇要檢查的element跟jQuery validate 1.11.1不同,例如:
jQuery validate 1.8.1: <input type="text" value="" class="required" />
jQuery validate 1.11.1: <input type="text" value="" required />

使用上jQuery validate 1.11.1比較方便,但相容性只到IE 8(使用jQuery 1.7.2的情況下)。

設定上也很容易,大概如下使用,可以在按下submit後,檢查下有
$('#myform').validate({

    submitHandler:function(form){
        //驗證成功準備要submit前
        if( !$('#check').prop('checked') ) alert('請勾選');
        else {
            //這邊我用ajax
            $.ajax({
                url: "mail.php", //自己寫好的mail,phpMail寫的
                async:false,
                type: "POST",
                data: $( "#myform" ).serialize(),
                success: function(data) {
                    alert(data);
                    $( "#myform" )[0].reset();
                }
            });
        }
    },
    messages: {
        //針對name及tel,指定沒填時要顯示的提示
        name: { required: ' 請輸入'},
        tel: { required: ' 請輸入'}
    }
});

相對應的element如下
<form id="myform" method="post" action="">
<input type="text" name="name" class="required">
<input type="text" name="tel" class="required">
</form>


css可以改成這樣(取自jQuery Validation Plugin Demo的demo)
<style type="text/css">
    label.error, label.error {
        color: red;

        font-style: italic;
    }
    input.error, textarea.error, checkbox.error {
        border: 2px dotted red;

    }
</style>


最後要將form的資料reset,要用$('#myform')[0].reset(),這樣才能正常抓到form這個element,因為$('#myform')是jQuery的物件,而reset()是Element的function


jQuery plugin Validation的7個Callback介紹
jQuery Validation Plugin Demo
jQuery Validation Plugin
jQuery Validation not working in IE7 + IE8

form reset
How to reset (clear) form through javascript?

2013年10月3日 星期四

[Block] xxxxxxxxxx ran insecure content from http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css

出現這種奇怪的問題,例如:
[Block] xxxxxxxxxx ran insecure content from http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css

主要原因是明明正在https中,script link卻在http,這狀況其實只要將"http:"這串字拿掉,留下//ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css,這樣就不會有這個error出現了

參考網址:
HTTPS-friendly jQuery CSS theme from Google CDN

2013年9月28日 星期六

Spring、J2EE學習筆記-submit中文的問題

同樣的錯又犯了一次,使用spring或j2ee開發的話,若submit的資料中有中文字,要在取得資料時,先執行以下指令,這邊做個紀錄,免得以後又犯

request.setCharacterEncoding("UTF-8");

另外查了下資料,也有幾個地方要注意
1. 在web.xml中要加入
<filter>

    <filter-name>characterEncodingFilter</filter-name> 
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>     <init-param> 
        <param-name>encoding</param-name> 
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>


2. JSP中要加入
<%@page contentType="text/html" pageEncoding="UTF-8"%>

3. server.xml中的conntector要加入useBodyEncodingForURI
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" useBodyEncodingForURI="true"/>



參考網址:

2013年9月23日 星期一

Hibernate學習筆記 - Error for: id numeric(19,2) identity not null

在用ant執行hbm2ddl來建table時,出現個問題,id的type設成big_integer,sql產生出一段底下的sql

id numeric(19,2) identity not null

本以為export出sql且ant回應build success是ok的,但發現table根本沒有create,將sql整個執行過後發現,sybase(可能其他DB也是有)要求numeric(19,0)才能正常運作,我針對id的宣告如下:

<id name="id" column="id" type="big_integer">
    <meta attribute="field-description">xxx</meta>
    <meta attribute="use-in-tostring">true</meta>
    <meta attribute="use-in-equals">true</meta>
    <generator class="native" />
</id>


想說就直接加成這樣,將precision設成10,scale設成0

<id name="id" type="big_integer">
    <column name="id" precision="10" scale="0" />
    <meta attribute="field-description">xxx</meta>
    <meta attribute="use-in-tostring">true</meta>
    <meta attribute="use-in-equals">true</meta>
    <generator class="native" />
</id>


但~ 不能用,找了很久的資料都找不到,結果跟generator一樣,是順序問題,如下設定就好了

<id name="id" type="big_integer">
    <meta attribute="field-description">xxx</meta>
    <meta attribute="use-in-tostring">true</meta>
    <meta attribute="use-in-equals">true</meta>
    <column name="id" precision="10" scale="0" />
    <generator class="native" />
</id>


參考網址:
Chapter 5. Basic O/R Mapping
Re: want to force scale=0 attr in hbm for BigInteger

2013年9月22日 星期日

JSTL學習筆記-JSP上取得session的資料

需求:
  • 在jsp上不用java code方式取得session的資料

在jsp上,session的預設object是sessionScope,所以只要直接使用sessionScope即可,例如,要取得在session中設好的userId,直接寫

${sessionScope.userId}


參考網址:
Print session attributes in jsp
How to use the values from session variables in jsp pages that got saved using @Scope(“session”) in the mvc controllers

JSTL學習筆記-jstl比對class name

JSTL使用的越多,就越覺得好用,今天正好遇到想要在jsp檢驗class,通常會想到用instanceof,不過其實有更快的做法,例:

targetObject.class.name == 'class_name'

上述即檢查targetObject是否為class_name的instance

做下記錄

參考網址:
how do i check for instance of a bean using jstl ?

2013年9月16日 星期一

Spring學習筆記-編譯spring 3.2.X

因為耍笨想要玩新玩意,莫名其妙變成在搞spring,spring目前不再提供jar檔,所以像我一樣老派的,就只能想辦法,最後找到這個Building a distribution with dependencies,還好其實還是有提供,大概步驟如下:

Step1. 將Github的master改成3.2.x再下載成zip或整個git下載
Step2. 解開zip後進入根目錄(例如我的是spring-framework-3.2.x)
Step3. 執行./gradlew depsZip(我是用mac,windows改用.bat)

再來就慢慢的等吧....最後在src下的每個專案都有各自的jar檔在目錄下

2013年9月7日 星期六

Javascript學習筆記-取得目前的url資訊

需求:用javascript取得目前的hostname

做法:
用window.location.hostname。

Example:
var hostname = window.location.hostname;

var hostname = location.hostname;

上圖取自:Javascript hostname屬性

如上圖,可以用location取得整個link或帶上的參數,或是哪種protocol,再自行運用


參考網址:
Javascript hostname屬性

2013年9月2日 星期一

iOS開發筆記 - int8_t及Byte的小差別

在寫iOS app時,宣告byte陣列使用時(尤其是在網路封包的raw data上),我個人在查資料時,最常見的是int8_t,不過在我實際使用上,卻發現一個小差別,最好還是用Byte,例如:

int8_t aa = (int8_t) 0xe0;
Byte bb = (Byte) 0xe0;


NSlog(@"data: %02x",aa);  --> 顯示:e0
NSlog(@"data: %02x",bb);  --> 顯示:e0

像上述這樣寫,是沒有差別的,使用上是ok的,但如果是接收資料再從NSData轉換過來就有不同了,例如,假設NSData *aa的第一個元素是e0

int8_t *rawData = malloc(sizeof(int8_t) * aa.length);
[aa getBytes:rawData length:aa.length];
NSlog(@"data: %02x", rawData);  --> 顯示:ffffffe0

Byte *rawData = malloc(sizeof(Byte) * aa.length);
[aa getBytes:rawData length:aa.length];
NSlog(@"data: %02x", rawData);  --> 顯示:e0

若要直接操作byte元素,還是最好用Byte會比較不會有不知名的錯誤。

2013年8月29日 星期四

Spring、J2EE、Hibernate學習筆記-could not initialize proxy - no Session

記錄一種狀況,在spring中使用hibernate是很常有的事,尤其在hbm中將兩個table的資料做聯集,不過遇到個狀況,記錄如下:

先取得人員的資訊(其中聯集到此人員的角色資訊),但事後要用時卻出現Exception如下:
could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session


看起來是預設聯集另一個table時是用lazy的方式,加上用的是spring的
HibernateTemplate,會自動close session,在hbm file那個field的property attribute加上lazy="false",這樣就ok了

2013年8月28日 星期三

Tomcat筆記-在ie中無法直接下載rar

Tomcat中內建的mime type沒有rar,所以照下列步驟處理

Step1:cd {Tomcat安裝目錄}/conf
Step2:vim web.xml
Step3:在Default MIME Type Mappings的區塊中,加入底下的code
<mime-mapping>
    <extension>rar</extension>
    <mime-type>application/x-rar</mime-type>
</mime-mapping>


Step4: 重啟server
Step5: 清掉IE的cache,再試一次就ok了

2013年8月20日 星期二

Spring、J2EE學習筆記-更動Tomcat內的jvm options

想要更動tomcat取用的memory量,找半天找不到在哪設,查了下資料才知道在shell script中,步驟如下

Step 1: cd {Tomcat安裝目錄}/bin
Step 2: vim catalina.sh
Step 3: 加入以下(設定是參考Help: Tomcat crashing with "org.apache.jk.common.ChannelSocket processConnection"

#JAVA_OPTS="-server -d64" (我的server不是64位元,所以mark掉)
JAVA_OPTS="$JAVA_OPTS -Xms2048m -Xmx2048m"
JAVA_OPTS="$JAVA_OPTS -XX:PermSize=300m -XX:MaxPermSize=300m"
JAVA_OPTS="$JAVA_OPTS -XX:NewSize=1024m -XX:MaxNewSize=1024m"
JAVA_OPTS="$JAVA_OPTS -XX:TargetSurvivorRatio=90 -XX:SurvivorRatio=5 -XX:MaxTenuringThreshold=12"
JAVA_OPTS="$JAVA_OPTS -XX:+CMSClassUnloadingEnabled"


我其實主要只是想設定2048的memory,哈

參考網址:
Help: Tomcat crashing with "org.apache.jk.common.ChannelSocket processConnection"
tomcat jvm options
add jvm options in tomcat

Spring、J2EE學習筆記-org.apache.jk.common.MsgAjp processHeader 嚴重的: BAD packet signature 18245

查看到log有底下的訊息

2013/8/15 下午 10:00:57 org.apache.jk.common.MsgAjp processHeader
嚴重的: BAD packet signature 18245
2013/8/15 下午 10:00:57 org.apache.jk.common.ChannelSocket processConnection 嚴重的: Error, processing connection
java.lang.IndexOutOfBoundsException
at java.io.BufferedInputStream.read(BufferedInputStream.java:310)
at org.apache.jk.common.ChannelSocket.read(ChannelSocket.java:628)
at org.apache.jk.common.ChannelSocket.receive(ChannelSocket.java:585)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:693)
at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
at java.lang.Thread.run(Thread.java:662)

查了下資料,發現還蠻多人有這狀況,主要是有人查了8009這個socket,用netstat -na看了下,也沒發現有process在用,這倒是讓我覺得有人在掃這個IP,不很好幾個小時一次,看了下資料都是在tomcat的server.xml中將<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />給mark掉即可,稍微看了下ajp是什麼

The Apache Tomcat Connector - AJP Protocol Reference
Apache JServ Protocol(wiki)

看起來是綁定web server和application server的binary protocol,細節沒測試不知道,猜是tomcat和apache綁定80有關,總之拿掉那行後看來是沒有exception了。

參考網址:

2013年8月19日 星期一

iOS開發筆記 - 取消圖示上的光影

有個需求要取消圖示上半圓的光影,印像是將Prerendered打勾,不知道為什麼一直取消不掉,只好找下資料,看到的方法都一樣,記錄在底下:

1. 先在專案 Target 的 Summary 標籤頁下找到 App Icons項
2. 在 “Prerendered” 打上鉤。
此时在info.plist里会多出一个配置项 "Icon already includes gloss effects"
3. 再找到 “Icon files (iOS 5)” 專案(如果有的話)展開,把裏面的 “Icon already includes gloss effects” 設置成 “YES”

不過仔細用以往的經驗想了下,可能是Resources被cache,只好"Command"+"Shift"+"K",先清一清專案重新編譯,裝置原本裝好的刪掉,再重新裝上去,就ok了

2013年8月14日 星期三

iOS開發筆記 - NSArray及NSDictionary的writeToFile: atomically:存檔失敗,但無Exception

NSArray及NSDictionary有個方便的writeToFile的function可以用,但發現若是裡頭有個元素是NSNull時,存檔會失敗,而且還沒有任何的exception,一般在使用時,是不會想到用NSNull,但我主要是在用AFNetwork時,發現它在解析JSON時,若null的元素會直接設NSNull。

推敲原因,猜測是因為NSNull並沒有實作Archive(實作了也很奇怪),而內定的Class都有,所以若有可能取得的NSArray及NSDictionary之中有元素可能有NSNull,要記得writeToFile前,先將那個元素remove或設成內定Class或能Archive的元素,才能成功儲檔。

2013年8月13日 星期二

Hibernate學習筆記 - org.hibernate.MappingException: No Dialect mapping for JDBC type: -1

試了半天也找了很多的資料,就是看不到有什麼解釋,只知道在設定hbm中設定property的type時,若使用的是sybase資料庫,type設定成text會有問題,會一直出現下列的Exception:
org.hibernate.MappingException: No Dialect mapping for JDBC type: -1

猜就是type不支援。查了資料,大多都說Text是varchar(4000),要用就type="string" length="4000",這樣設定就過了,不過4000也太大了吧

2013年8月11日 星期日

2013年8月8日 星期四

iOS開發筆記 - 使用Regular expression比對電話前置字串

做個紀錄

需求:
  • 針對+86 123234534或+886 097xxxxx
大概的寫法是:

NSError *error = NULL;
NSRegularExpression *regex 

   = [NSRegularExpression regularExpressionWithPattern:@"^[\\+][0-9]+(\\s)|^[\\+]" options:NSRegularExpressionCaseInsensitive error:&error];

NSString *mobile = @"+86 123456789";
NSString *modifiedString = [regex stringByReplacingMatchesInString: mobile options:0 range:NSMakeRange(0, [mobileChanged length]) withTemplate:@""];

NSLog(@"%@", modifiedString);


這樣就ok了~

參考網址:
NSRegularExpression Class Reference
User regular expression to find/replace substring in NSString

iOS開發筆記 - NSString取代字串中某個文字

記錄一下,NSString取代字串中某個文字的方式

NSString *str = @"This is a string. That is a string";
str = [str stringByReplacingOccurrencesOfString:@"string" withString:@"duck"];


這方式會搜尋整個字串,用後面的字取代所有符合前面字串的字

2013年8月4日 星期日

iOS開發筆記 - TTTAttributedLabel的使用

最近對UILable有些需求:
  1. 有link點擊
  2. 若是電話號碼可以打電話
  3. 若是連結可以開網址
  4. 若是地圖可以開Apple Map
找到了個不錯的元件可以符合上述的需求:TTTAttributedLabel,下載點:mattt / TTTAttributedLabel

mattt / TTTAttributedLabel有蠻完整的範例,不過這邊還是紀錄一下。

Step 1:
COPY兩個檔案:TTTAttributedLabel.h及TTTAttributedLabel.m

Step 2:
加入CoreText.framework

Step 3(若專案本身是ARC不需要這步驟):
至Build Paases -> Compile Sources中找到TTTAttributedLabel.m加入-fobjc-arc

再來就可以使用了。以我自己的為例:

先將要使用這元件的ViewController或Class加上TTTAttributedLabelDelegate

電話號碼:
TTTAttributedLabel *tel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(10, 10, 190, 21)];
tel.delegate = self;

if (tel.text != nil && ![tel.text isEqualToString:@""])  { 

    //電話號碼的範圍是整個字串

    [tel addLinkToPhoneNumber:tel.text withRange: [tel.text rangeOfString:tel.text] ];
}


開網址:
TTTAttributedLabel *webSite = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(10, 10, 190, 21)];
webSite.delegate = self;
if (webSite.text != nil && ![webSite.text isEqualToString:@""]) {
    //網址的範圍是整個字串
    NSURL *urlString = [[NSURL alloc] initWithString:[@"http://" stringByAppendingString: webSite.text]];
    [webSite addLinkToURL:urlString withRange:[webSite.text rangeOfString: webSite.text] ];
}

開Apple Map:
TTTAttributedLabel *addrLabel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(10, 10, 190, 21)];
addrLabel.delegate = self;
if (addrLabel.text != nil && ![addrLabel.text isEqualToString:@""]) {
    //地址的範圍是整個字串
    NSDictionary *addr = @{@"addr": addrLabel.text};
    [addrLabel addLinkToAddress:addr withRange: [addrLabel.text rangeOfString: addrLabel.text] ];
}


還蠻簡單易用。

2013年7月28日 星期日

iOS開發筆記 - NSUserDefaults的使用

以前都很辛苦的用sqlite或NSDictionary去紀錄一些使用者的資料,沒想到其實apple已經很貼心的做了一個好用的NSUserDefaults,可以簡單的紀錄一些資訊,說簡單也是能紀錄所有Cocoa上的所有Object(除了自訂的資料型態,要自行處理)。

使用上很容易,如下所示:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:string forKey:@"Hello world"];
NSArray *array = @[@"123",@"456"];
[userDefaults setObject:array forKey:@"Array"];
BOOL isValid = YES;
[userDefaults setBool: isValid forKey:@"isValid"];
int number = 100;
[userDefaults setInteger:number forKey:@"number"];


要注意的是,設定好後只是單純的cache住,要存進硬碟要用,才真正儲存
[userDefaults synchronize];

取值很容易
[userDefaults stringForKey:@"Hello world"];
[userDefaults arrayForKey:@"Array"];
[userDefaults boolForKey:@"isValid"];
[userDefaults integerForKey:@"number"];


參考網址:
NSUserDefaults (plist) 筆記
返璞归真,忘掉NSUserDefaults
NSUserDefaults Class Reference
NSUserDefaults customize behavior to match a user’s preferences

2013年7月25日 星期四

CentOS筆記-安裝LAMP

前陣子用阿里雲的系統:CentOS 6.3,建好是一整個空的系統,連Apache、MySQL都沒有,真的空空如也,只能自己加上去,這邊記一下步驟:

安裝Apache http server
yum install httpd
service httpd start


修改/etc/httpd/conf/httpd.conf中<Directory "/var/www/html">下的Options
Options Indexes FollowSymLinks
改成Options -Indexes FollowSymLinks

安裝Mysql Server
yum install mysql-server
service mysqld start
/usr/bin/mysql_secure_installation


若要安裝5.5版,可以看CentOS筆記-CentOS 6.5 安裝MySQL 5.5

最後一個指令可以設定root密碼,將一些用不到的table及權限去除(link: MySQL Server 安裝後的設定

安裝PHP
yum install php php-mysql php-mysqli php-mbstring

重啟
chkconfig httpd on
chkconfig mysqld on


service httpd restart
service mysqld restart

這樣一個基本的LAMP就架起來了

架phpMyAdmin
我習慣用phpMyAdmin,所以再到PhpMyAdmin Home下載最新的tar檔,上傳到/var/www底下解開後,我是都會改目錄名稱為myadmin,用http://{hostname或ip}/myadmin,就可以用了,不過這次卻發生CentOS筆記-PHP Fatal error: Call to undefined function mb_detect_encoding()中提到的問題,就再依文中所提處理即可。

若有要安裝wordpress,是要再注意/etc/httpd/conf/httpd.conf中
LoadModule rewrite_module modules/mod_rewrite.so <-- 這個要有

檔案最後再加上底下幾行(主要是Rewrite那幾行)
AddType application/x-httpd-php .php .phtml

RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]


記得再重啟http server

參考網址:
How to Install Linux, Apache, MySQL, PHP (LAMP) stack on CentOS 6
新安裝 CentOS 6.5 筆記

2013年7月24日 星期三

AdSense-申請 part 4

過了超久,我終於申請到AdSense,經過上次的幾次教訓,這次重新看了下自己AdSense-申請 part 2寫的東西,每次的回應都是
感謝您對 Google AdSense 感興趣。在審查過您的申請之後,我們的專員發現您的申請並不符合我們的計劃條件。因此,我們無法讓您加入我們的計劃。
想了想,重新注意到底下的訊息
重要注意事項:
* 您必須安裝廣告程式碼,我們才能完成審查手續。如果不知道怎麼在 Google 擁有的 API (如 YouTube) 上安裝廣告程式碼,請參考:xxxxx
* 您的廣告開始出現後,請不要點擊自己的廣告,就算是為了測試也不可以,否則就算違反 AdSense 計劃政策 (https://www.google.com/adsense/policies)。

查了下官網中的建立廣告單元,之前都是直接在加入Blogger中的Adsense元件,會不會其實還是篏入javascript比較實在,當下再重新申請,這次很快就有了初步通過的回應,取得上述的回應後,這次改用“HTML/JavaScript”,大概的動作如是:

Step1: 按下版面配置 > 新增小工具 > HTML/JavaScrip
Step2: 進入AdSense的帳戶中,新增一個廣告單元(這邊有教學:建立廣告單元
Step3: 點選新建好的廣告單元上的“獲取代碼”,出現javascript,整個copy
Step4: 貼到HTML/JavaScrip的內容中,標題可以不用

這樣就ok了,再來就是等了,偶爾也要記得更新下文章,祝好運....

參考網址:
建立廣告單元
关于 HTML 的简单说明
使用已关联 AdSense 帐户在我自己的网站上展示广告

iOS開發筆記 - NSArray check NSNull

使用AFNetwork中的JSON時,因為JSON傳回來的有時是null值,取到時常是NSNull而不是null值,所以在檢查時不能用null,而要用[NSNull null],但NSArray的object在直接比較時,就會出現NSArray無法和NSNull比較的問題,例如:

NSArray *array = (從JSON取得值,但是是NSNull型態回傳)
if( array != [NSNull null] ) {
  //做要做的事
}


但上述的if是有問題的,所以要改用下述的方式

NSArray *array = (從JSON取得值,但是是NSNull型態回傳)
if( array != (id)[NSNull null] ) {
  //做要做的事
}


有點怪怪的,只能說我個人基礎沒打好,要再多訓練

參考網址:
ios check if nsarray == null

2013年7月23日 星期二

iOS開發筆記 - 另一些讓UILabel的字置頂的做法

最近正好有需要,卻忘了自己有寫iOS開發筆記-如何讓UILabel的字能置中且在頂端,還去找,不過倒是因此找到一篇让UILabel的文字顶部对齐,他的第一個做法跟我的做法類似,但多了方式,這邊做個紀錄好了。

===========================================================
原文的三個方法如下(這邊貼上的程式碼都屬於让UILabel的文字顶部对齐的內容)

方法1:寬高設定,不過我使用上是要在設定numberOfLines=0
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *dateString = @"The date today is January 1st, 1999";
UIFont *dateFont = [UIFont fontWithName:@"Helvetica" size:14];
CGSize dateStringSize = [dateString sizeWithFont:dateFont
    constrainedToSize:maximumSize
    lineBreakMode:self.dateLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(10, 10, 300, dateStringSize.height);
self.dateLabel.frame = dateFrame;


方法2:在最後加\n,\n的個數最好和numberOfLines的數字一樣,例如numberOfLines=2,則最後是"\n\n ",這是實際用的感覺,我也是用這方法
for(int i=0; i<newLinesToPad; i++)
    self.text = [self.text stringByAppendingString:@"\n "];

方法3: catogory方式改動UILabel

// -- file: UILabel+VerticalAlign.h
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end

// -- file: UILabel+VerticalAlign.m
@implementation UILabel (VerticalAlign)
- (void)alignTop {
    CGSize fontSize = [self.text sizeWithFont:self.font];
    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label
    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
    for(int i=0; i<newLinesToPad; i++)
        self.text = [self.text stringByAppendingString:@"\n "];
}

- (void)alignBottom {
    CGSize fontSize = [self.text sizeWithFont:self.font];
    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label
    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
    for(int i=0; i<newLinesToPad; i++)
        self.text = [NSString stringWithFormat:@" \n%@",self.text];
}
@end


參考網址:
让UILabel的文字顶部对

2013年7月22日 星期一

iOS開發筆記 - NSDictionary key sort

NSDictionary如同hash table,它的key是沒排序過,查了下,其實可以用變通方式

Step 1: 先將Key排序做成一個array
NSArray * sortedKeys = [[keys allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)];

Step 2: 使用時用做出來的array來遞迴取出
for( Object *ob in sortedKeys ) {
    //你想做的事
}


這樣就是排好的了

參考網址:
sort NSDictionary values by key alphabetical order

2013年7月19日 星期五

CentOS筆記-安裝GIT

CentOS 5:
>yum install git

發現沒有GIT,只好自行下載,大概步驟如下:
>wget https://git-core.googlecode.com/files/git-1.7.11.1.tar.gz
>tar zxvf git-1.7.11.1.tar.gz
>cd git-1.7.11.1
>yum install zlib-devel openssl-devel cpio expat-devel gettext-devel
>./configure
>make
>make install


測試一下能不能用,打入
>git --verion

可以看到GIT的版本,不過我實際使用是從網路上取得,打上git clone https://xxx.com/xxx/new.git
卻出現:fatal: Unable to find remote helper for 'https'

查了下發現可能是curl的問題,所以GIT要再compile進curl,指令如下:
>yum install curl*
>cd git-1.7.11.1
>./configure
>make


再輸入git clone https://xxx.com/xxx/new.git,發現可以取得code了

CentOS 6:yum上面有git可用
>yum install git


參考網址:
Centos 5.8 install your own git server
repo下载android出现fatal: Unable to find remote helper for 'https'问题的方法
git clone: fatal: Unable to find remote helper for 'https'

2013年7月13日 星期六

CentOS筆記-PHP Fatal error: Call to undefined function mb_detect_encoding()

安裝phpmyadmin時,發現有底下的error

PHP Fatal error:  Call to undefined function mb_detect_encoding() in /var/www/html/mysqladmin/libraries/php-gettext/gettext.inc on line 177

猜測是少了某個套件,一查下果然,是少了mbstring

使用底下指令安裝php這套件後,就好了
> yum install php-mbstring

參考網址:
Simple HTML Dom - Fatal error when using load_file

2013年7月4日 星期四

CentOS筆記-設定https

Step1. 確定有Apache server

Step 2. 確定有openssl,沒有的話執行
yum install openssl
(記得用/sbin/service httpd configtest檢查)

Step 3. 確定有安裝mod_ssl,沒有的話執行
yum install mod_ssl

Step 4. 產生認證
1. cd /etc/pki/tls/private
2. 產生2048的key: openssl genrsa -out private.key 2048
3. 產生憑證檔請求檔: openssl req -new -key private.key -out https.csr
4. 自行產生x509憑證檔:open x509 -req -days 365 -in https.csr -signkey private key -out server.crt
(正常下是要請CA用憑證檔請求檔來產生x509憑證檔,要花錢)

這樣這兩個檔都放在/etc/pki/tls/private(可以自行放在想要的位置)

Step 5. 編輯ssl.conf,找到
SSLCertificateFile /etc/pki/tls/private/server.crt
SSLCertificateKeyFile /etc/pki/tls/private/private.key

Step 6. 檢查設定及重啟
/sbin/service httpd configtest
/sbin/service httpd restart

這樣就行了

參考網址:
Apache 開啟 HTTPS
http://disp.cc/b/11-3UNW
DER vs. CRT vs. CER vs. PEM Certificates and How To Convert Them

2013年6月30日 星期日

Wordpress開發筆記-拿掉後台管理區上那煩人的更新訊息

之前很多網站都用Wordpress開發,總會在最上面有個wordpress更新,給客戶看到總怪怪的,關掉它的理由:

  1. 客戶看到很怪也有會問那是什麼
  2. 總也有好奇心強的客戶就給它按下去,最後沒完沒了的收拾

最後結論:關掉它吧

但這好像是內定的,沒地方處理,找到這篇如何關閉 WordPress 管理後台的「版本更新」通知?,看起來除了改掉沒什麼方式,所以改掉方式如下:

Step1: 找到wp-admin/includes/update.php,最好先備份一下
Step2: 打開update.php,找到“echo "<div class='update-nag'>$msg</div>";”就comment掉

再進入後台就ok了。不過若是做了更新,要記得再做一次就是

參考網址:
如何關閉 WordPress 管理後台的「版本更新」通知?

2013年6月25日 星期二

CentOS筆記-fsockopen()被SELinux擋掉

裝好centOS 6後,預設SeLinux是開啟的,我懶的關掉他,不過他倒是造成了像我這篇CentOS筆記-postfix服務與php mail()所述的問題,今天又發現用fsocketopen會有問題,查到Enable remote fsockopen() in PHP on Fedora (SELinux)這篇,才發現又有個要設定,如下述指令,打開後就ok了
setsebool -P httpd_can_network_connect 1

可以用底下這個來看剛才的動作有沒有成功(查詢server上有哪些動作的message)
tail /var/log/messages

參考網址:
Enable remote fsockopen() in PHP on Fedora (SELinux)
SELinux, Apache/httpd, PHP establishing socket connections using fsockopen() et al

2013年6月24日 星期一

Wordpress開發筆記-json_encode

有個需求
  1. 取得訊息,轉成json格式
  2. 當成post的meta存進資料庫

使用get方式丟上中文message後,本以為message有url encode過,再來用json_encode就沒問題了,卻發現取得時本來應該要是\U1234這樣的格式變成U1234的樣子存進資料庫,本以為是GET的中文出問題,但從$_GET取得時,是正常呈現。

找半天才發現是add_post_meta及update_post_meta會將“\”去除,若用json_encode過,會將中文都變成無法還原的亂碼。所以

Step1: 取得數值
$value = $_GET['test'];

Step2: 轉json格式
$value = json_encode($value);

Step3: url encode將“\”轉成ascii code
$value = urlencode($value);

Step4: 存進資料庫
add_post_meta(post_id,'message', $value);

記得取出時要decode回來,如:
$value = urldecode(get_post_meta(post_id,'message'));

參考網址:
解決json_encode中文UNICODE轉碼問題
解決PHP JSON 中文亂碼的問題

2013年6月19日 星期三

iOS開發筆記 - 取得目前時間和指定時間剩多少時間

需求:
  1. 一特定時間距目前時間多久
  2. 分成天時分
//Step 1: 通常輸入都有個固定模式,這邊先用yyyyMMddHHmm

NSDateFormatter *format = [[[NSDateFormatter alloc] init] autorelease];
format.timeStyle = NSDateFormatterNoStyle;
format.dateFormat = @"yyyyMMddHHmm";

//Step 2: 轉換成NSDate
NSDate *date = [format dateFromString:temp.endTime];

//Step 3: 取得和目前差距時間
NSTimeInterval sinceNow = [date timeIntervalSinceNow];

//Step 4: 取得天時分的倒數
int day = floor(sinceNow/86400);
int hour = floor((sinceNow - day * 86400)/3600);
int min = floor((sinceNow - day * 86400 - hour * 3600)/60);


很簡單,不過這邊的程式碼可以優化,我懶 XD

參考網址:
How to convert an NSTimeInterval (seconds) into minutes
關於 NSDateFormatter 的二三事

2013年6月18日 星期二

iOS開發筆記 - nil? Null? [NSNull null]?

老是在用nil、Null,卻從沒想過之間的分別,看了幾篇文章,其實都是一樣,只是為了可讀性(這很重要),不過大概的分別如下:

nil: 給Object-C object用
Nil: 給Object-C class用

個人觀感: 关于 [NSNull null] 的一些疑惑有提到一些Demo,但說實在我感受不出來差別,我都用nil

NULL: C opinter用
個人觀感:例如@seleter這類的pointer,我都用nil,看來要好好學起來

NSNull: 一個讓人用的null class,使用上會抛出NSException
個人觀感:第一次用時,發現一直丟出Exception,覺得煩人,但我個人覺得比nil讓人更清楚,不過nil還是方便好多吶


底下轉貼nil / Nil / NULL / NSNull上的結論



參考網址:
关于 [NSNull null] 的一些疑惑
Are NULL and nil equivalent?
nil / Nil / NULL / NSNull

2013年6月16日 星期日

Code Style - HTML中的attribute的值要記得加上雙引號包住

很多時候的bug,只是很單純的一個逗點沒打,一個符號打錯,大部分的時候都是正確的,只有某些狀況出現,就一切都掛點了,例如底下這樣的寫法:

<td><input size="15" type=text name="test[]" value='.$value.'></td>


其實沒什問題,大部分狀況是ok的,因為瀏覽器會自動幫忙處理,但這段程式有個問題,value這部分要是$value的值是有空格的,那就會發生空格後的值都消失了,改成

<td><input size="15" type=text name="test[]" value="'.$value.'"></td>


重點是加上雙引號,就ok了,其實是很小的問題,但卻搞到整個系統資料大亂,找還找不出來,有些好習慣是一定要好好培養,不然bug解不完

2013年6月9日 星期日

sqlite學習筆記 - sqlite初體驗

sqlite是我從來沒用過,但在手機端還真的好用,一般的linux或mac os x都內建,這邊就稍微記錄一下從無到有做一個user_meta的table,放個資料做個select

Step1: 創建一個名叫xxx的DB
>sqlite3 xxx.db

執行完會進入sqlite3的command link
Step2: 建立table
sqlite> create table user_meta (id integer primary key, meta_key varchar(50), meta_value varchar(300));

Step3: 測試一下,insert一筆
sqlite> insert into user_meta(meta_key, meta_value) values('account','alvin');

Step4: 測試一下,select
sqlite> select * from user_name

顯示--> 1|account|alvin

Step5: 離開
sqlite>.exit

超簡單~

2013年6月7日 星期五

iOS開發筆記 - UIBackgroundModes & Newstand features failed

有朋友又請教我一個問題,如下圖:

查了下,發現這是指app是Newsstand的app,內容是敘述要上架的東西,照著iOS 5 newsstand application icon所提就可以解決,不過討論完後,根本不需要啊~都砍光光~比較快~

突然覺得還是都貼過來比較放心,iOS 5 newsstand application icon討論串就貼在底下了

I just did a quick test. In my project I put the icon files in the main app directory, where main.m resides. They are called Icon.png and Icon@2x.png for the application icons, and Newsstand-Cover-Icon.png and Newsstand-Cover-Icon@2x.png
The CFBundleIcons section of the *.plist file (found in the main app directory) looks like this:
<key>CFBundleIcons</key>
<dict>
    <key>CFBundlePrimaryIcon</key>
    <dict>
        <key>CFBundleIconFiles</key>
        <array>
            <string>Icon.png</string>
            <string>Icon@2x.png</string>
        </array>
    </dict>
    <key>UINewsstandIcon</key>
    <dict>
        <key>CFBundleIconFiles</key>
        <array>
            <string>Newsstand-Cover-Icon.png</string>
            <string>Newsstand-Cover-Icon@2x.png</string>
        </array>
        <key>UINewsstandBindingType</key>
        <string>UINewsstandBindingTypeMagazine</string>
        <key>UINewsstandBindingEdge</key>
        <string>UINewsstandBindingEdgeLeft</string>
    </dict>
</dict>
Other relevant sections of the *.plist file are set to this:
<key>UIBackgroundModes</key>
<array>
    <string>newsstand-content</string>
</array>


<key>UINewsstandApp</key>
<true/>
You may have to build and launch your app on the device a couple of times, before the icons appear on the Newsstand shelf.
You can edit *.plist files with a text editor like TextWrangler (free), TextMate (paid), or MacVim (free).
Hope this helps!

參考網址:
iOS 5 newsstand application icon
Contents of the UINewsstandIcon Dictionary

iOS開發筆記 - icon specified in the Info.plist

看到這個,莫名其妙


查了下info.plist,發現icon file list有多了個空的

會掉它,就解決了。

總覺得雖然都相同的訊息,但大家遇到的狀況好像都不同

參考網址:
App Icons on iPad and iPhone
icon Specified in the info.plist error
iTunesArtwork breaking release submit to app store

2013年6月6日 星期四

iOS開發筆記 - 幾個大陸社群網站iOS SDK整合的初步查看

微博
>>>>>>>>>>>>>>>>
API site:http://open.weibo.com/wiki/IOS_SDK

開發者申請:用微博或新浪的帳號
資料填寫如下圖:




功能(從sample code抄下來的):
  • 登入整合:有
  • 取得自己的資料:有
  • 取得自己的timeline
  • 貼訊息(文字及圖)

QQ
>>>>>>>>>>>>>>>>
API site:http://wiki.opensns.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91IOS_SDK%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E


開發者申請:用QQ的帳號
申請時資料填寫如下圖:



功能(從sample code抄下來的):




  • 登入整合:有
  • 分享(?)
  • 取得會員訊息
  • 取得相簿
  • 發表說說
  • 取得相簿列表
  • 驗證空間粉絲
  • 創建空間相簿
  • 發表日誌
  • 設制個人圖像
  • 基本會員信息
  • 詳細會員信息
  • 微博好友提示
  • 微博好友提示
  • 退出

微信
>>>>>>>>>>>>>>>>
API site:http://open.weixin.qq.com/

開發者申請:用QQ的帳號,不用申請QQ的開發者認證,是裡頭最簡單的


功能:

  • 登入整合:沒有
  • 對著朋友傳訊息(文字、照片、link等)
  • 貼訊息上自己的朋友圈


說實在,會員的申請好難用啊,尤其是QQ的密碼要是弄丟了,要你提供訊息就算了,還要三個人的認證,然後再等上個幾個小時,我個人要求密碼(沒人認證),等了四個小時後被回絕,一氣之下重申請,爛爆了~~~~~

微博在申請帳號時,簡訊一直傳不來,尤其是他的雲端服務,要我自行再寄信去要認證碼....昏了

大陸祖國的東西我實在.....

2013年6月2日 星期日

iOS開發筆記 -NSDate用字串初始及轉回字串

NSString -> NSDate
=======================================

NSDateFormatter *format = [[[NSDateFormatter alloc] init] autorelease];

format.timeStyle = NSDateFormatterNoStyle;
format.dateFormat = @"yyyy/MM/dd";
NSDate *date = [format dateFromString:@"1970/01/01"];


NSDate -> NSString
=======================================

NSDateFormatter *format = [[[NSDateFormatter alloc] init] autorelease];

format.timeStyle = NSDateFormatterNoStyle;
format.dateFormat = @"yyyyMMdd";
__birthField.text = [format stringFromDate:__birthPicker.date];


參考網址:
How can I initialize a date to NSdate?
Objective-C - NSString 和 NSDate 互相轉換

iOS開發筆記 - 限制UITextView的行數

UITextView有個貼心處,有scroll view,可以不限字數的一直填字,但有時就是希望只有可視範圍的大小,將scroll的功能disable後還是不夠,這時只能依靠UITextViewDelegate中的兩個function,來做到限定的功能,我在此的需求如下:

字數及游標只能在UITextView bound的範圍內

字數可以藉由底下的shouldChangeTextInRange來處理,若超過剛填入的字就去除,但若要讓游標到最後一行就停住,就得由textViewDidChange來控制,兩個的內容都一樣,但作用的點不同。

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    //防止使用者輸入字數超過輸入區
    if (textView.contentSize.height > textView.frame.size.height + 10) {
        textView.text = [textView.text substringToIndex:[textView.text length]-1];
        return NO;
    }
 
    return YES;
}

- (void)textViewDidChange:(UITextView *)textView
{
    //防止Enter鍵會讓游標下移超過輸入區
    if (textView.contentSize.height > textView.frame.size.height + 10) {
        textView.text = [textView.text substringToIndex:[textView.text length]-1];
        //        textView.contentSize = textView.frame.size;
    }
}


參考網址:
UITextView 限制行数解决方案
如何实现对UITextField ,UITextView等输入框的 字数限制

2013年5月31日 星期五

iOS開發筆記 - 得知UITextView的游標位置

有時需求是如此簡單,但卻找不到api可用,很怪。例如:想要取得UITextView的游標位置。居然還扯到private api。但還好用到好的關鍵字,還是找到了些資料,其實只要用底下的code,就可以找到游標在UITextView目前的所在位置(要在iOS 3.2之後的版本)

CGPoint cursorPosition 
  = [textView caretRectForPosition:textView.selectedTextRange.start].origin;
NSLog(@"x: %f, y: %f",cursorPosition.x, cursorPosition.y);


另外要記得確認selectTextRange不是nil

參考網址:
Cursor position in a UITextView
Pixel-Position of Cursor in UITextView

2013年5月25日 星期六

PHP開發筆記-PHP type comparison tables

PHP有一堆比較的function(is_set、is_null)及==或===,這堆有的沒的,朋友查到個網站指出PHP的官網有特別列出,在這做個紀錄,
網址:PHP type comparison tablesComparison Operators







以前很多事都是可以用就好,現在要好好追求用的對及用的精確

參考網址:
[PHP] empty(),is_null(),isset 判斷結果列表
PHP type comparison tables

2013年5月24日 星期五

iOS開發筆記 - hide statusbar在ipad上的怪狀況

iPad一般來說是可以正常執行只能在iphone上執行的project,但若隱藏上方的status bar,然後轉換到要秀出status bar(使用Modal切換),卻發現layout會上移(在iphone上是正常的),主要是本來畫面上有status bar,但從沒有status bar切換過來時,status bar還來不及出現,就過去了。針對這方面的處理,如下:

[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
[self dismissModalViewControllerAnimated:YES];


先要求status bar出現,再dismissModal,這樣在ipad上就正常了。

2013年5月14日 星期二

iOS開發筆記 - iPhone版的Number pad要注意的小問題

使用xib檔設定TextField使用Number pad時,發現到iPhone版的沒有return這個鍵,若是關閉或要按下return才能關閉此View時,會遭遇到無法關閉的狀況,若還是希望只能輸入數字,只能

1. 用Numbers and Punctuation,多出很多符號,但至少能用
2. 做成Scroll或關閉鍵可以在上面

做個紀錄

iOS開發筆記 - Random設值

偶爾總需要random取值,這邊記錄一下

底下的code取自:Getting a Random Number

// Get random value between 0 and 99
int x = arc4random() % 100;
// Get random number between 500 and 1000
int y = (arc4random() % 501) + 500);


參考網址:
Getting a Random Number
iOS Random Number Generator to a new view

2013年5月8日 星期三

2013年5月6日 星期一

iOS開發筆記 - “timed out waiting for app to launch”的問題

今天在執行程式時,一直發生“timed out waiting for app to launch”的問題,想不透是為什麼,查了下網路,找到這篇:Xcode 4.6 error - Timed out waiting for app to launch

看了下schema,才發現Run的地方選到了ad hoc,應該是要選擇debug或release這兩個才是。

2013年5月1日 星期三

iOS開發筆記 - 取得NSDocumentDirectory路徑

每次想取得ios app中的document目錄,就都要找找,一直忘記,這次就記起來

NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent: @"video.mp4"];


這表示取得MyDocuments下video.mp4檔案的路徑

2013年4月30日 星期二

Cocos2D學習筆記-Timers改用[schedule: interval:]

使用nstimer太習慣,不知不覺在cocos2d中就用起了nstimer,但在換sence後,若又換回同一個sence時,重覆個兩次就會發生無法invalidate的狀況(應該說我的做法不知道為什麼會init兩個timer),最後發現還是用schedule: interval:比較正確,理由有二

  1. 比較沒有延遲問題
  2. 不用手動unschedule,除非有必要(我的狀況正好是有必要)
使用方式如官方提供的範例:
/**********************************************************/
// OK OK OK OK OK
/**********************************************************/
-(id) init
{
    if( (self=[super init] ) ) {
        // schedule a callback
        [self scheduleUpdate];  // available since v0.99.3
        [self schedule: @selector(tick2:) interval:0.5];
    }

    return self;
}

-(void) update: (ccTime) dt
{
    // bla bla bla
}

-(void) tick2: (ccTime) dt
{
    // bla bla bla
}


非常簡單

參考網址:
cocos2d Best Practices

2013年4月24日 星期三

Wordpress開發筆記-利用post_name取得post


想用get_post取得,但不知道為什麼放入post_name,就是不行,即使用urlencode也不行,最後手段只好直接抓資料庫及取得url的post_name,code如下,不過總覺得資安問題存在....

$post_name = $_GET['(post_type的名稱)'];
       
global $wpdb;
$post_id = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_name = '".urlencode($post_name)."'");


參考網址:
get_id_by_post_name()

2013年4月22日 星期一

Wordpress開發筆記-超易用不顯示不必要admin menu的方式

有些menu在後台並不想讓使用者看到,免增加麻煩,這時就只要用下列的code就可以看是要拿掉工具、媒體庫呢~ 還是文章等等,還蠻方便的

function remove_menus () {
global $menu;
// $restricted = array(__('Dashboard'), __('Posts'), __('Media'), __('Links'), __('Pages'), __('Appearance'), __('Tools'), __('Users'), __('Settings'), __('Comments'), __('Plugins'));
$restricted = array( __('Posts'), __('Comments'), __('Links'), __('Tools'));
end ($menu);
while (prev($menu)){
$value = explode(' ',$menu[key($menu)][0]);
if(in_array($value[0] != NULL?$value[0]:"" , $restricted)){unset($menu[key($menu)]);}
}
}
add_action('admin_menu', 'remove_menus');



參考網址:
How to remove menus in WordPress dashboard

2013年4月21日 星期日

Cocos2D學習筆記-使用Accelerometer

發生了個問題,在CCLayer的init中將isAccelerometerEnabled設成YES,並實作了底下的code

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    self.accelerationY = acceleration.y * 10;
    CCLOG(@"acceleration.y: %f",acceleration.y);
    CCLOG(@"accelerationY: %f",self.accelerationY);
}

-(void) update:(ccTime)deltaTime
{
    CCLOG(@"__accelerationY: %f",self.accelerationY);
    CGFloat x = __human.position.x;
    if (self.accelerationY != 0) {
        x += self.accelerationY;
    }
    __human.position = ccp( x , __human.position.y);
}


本以為可以正常的執行,卻發現__accelerationY的值一直是0,非常奇怪,找了下資料才發現要在OnEnter中再設定delegate

-(void) onEnter
{
    [super onEnter];
 
    if( self.isAccelerometerEnabled )
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
}


這樣就ok了

參考網址:
weird issue with accelerometer

2013年4月18日 星期四

iOS開發筆記 - 讓app中的檔案可以借由iTunes取得

其實只要加入Application supports iTunes file sharing,設成YES,重新安裝app,並連上iTunes,就可以在檔案共享中,看到剛安裝的app的圖示在裡頭,點選後就可以用了


2013年4月16日 星期二

2013年4月5日 星期五

Parallel還真好用

原來將之前用Parallel做好的作業系統檔案copy到要放的位置,點兩下選確定複製個mac address,就可以直接使用了,不用再重安裝或重新確認是否開通等有的沒的步驟,方便多了

2013年3月25日 星期一

Cocos2D學習筆記-CCSprite記進相簿中

需求有兩個
  1. 將CCSprite存成檔案
  2. 存到相簿中
查了下資料,做法如下:

CCTexture2D *tx = [sprite1 texture]; //這邊是因為sprite1一直在更新,所以先copy
CCSprite *sprite = [CCSprite spriteWithTexture:tx];
sprite.anchorPoint  = CGPointZero;   //這個一定要有,尤其有更改過時

//先做成texture
CCRenderTexture *renderer = [CCRenderTexture renderTextureWithWidth:sprite.contentSize.width height:sprite.contentSize.height];
            
[renderer begin];
[sprite visit];
[renderer end];

UIImage *newImage = [renderer getUIImage];

//做成UIImage,就可以直接用UIImageWriteToSavedPhotosAlbum存檔
UIImageWriteToSavedPhotosAlbum(newImage,nil,nil,nil);




參考網址:
UIImage from CCSprite (yes I've already searched)
UIImage轉CCTexture2D UIImage轉CCSprite
[IPHONE]將照片儲存到IOS照片相簿(Photo Album)中

Cocos2D學習筆記-複製一個CCSprite

複製一個CCSprite無法直接用copy,要先取得texture再init,如下:


CCTexture2D *texture = [mySprite1 texture];
CCSprite *mySprite2 = [CCSprite spriteWithTexture: texture];


參考網址:
Copy a CCSprite

Cocos2D學習筆記-轉動圖片(使用SneakyJoystick)

使用SneakyJoystick蠻方便的,但我正好要用到SneakyJoystick的底圖是要跟著thumb一塊轉動,但怎計算都發現怪怪的,後來發現差了90度,所以在updatePositions中要改成底下這樣:

if(joystick && thumbSprite) {
    [thumbSprite setPosition:joystick.stickPosition];
    if (joystick.degrees == 0) {
        backgroundSprite.rotation = joystick.degrees;
    }
    else {
        CGFloat angle = joystick.degrees - 90.0f;
        backgroundSprite.rotation = -1 * angle;
    }
}


角度是0時,就直接給0,但不是0時,就轉90度,並加上個負號,這樣就能正常使用了

參考網址:
How do you rotate a CCSprite to face a touch

2013年3月18日 星期一

Javascript學習筆記-javascript字串中insert個字串

原生的javascript程式沒有字串insert的function的樣子(沒找到,有的話跟我說 XD),還蠻簡單的,就如下


String.prototype.splice = function( idx, rem, s ) {
    return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};

這樣就可以用了,如下使用

var result = "voo abc".splice(4,0," 111");

參考網址:
JavaScript: How can I insert a string at a specific index

2013年3月15日 星期五

Cocos2D學習筆記-如何從jpeg raw data轉成CCSprite

我的需求:
取得的jpeg raw data轉成CCSprite

做法:
//先取得raw data, 這邊會先copy到別處,是因為我會對data做些處理
uint8_t *imageData = (uint8_t*)malloc(sizeof(uint8_t) * jpegImageSize);
memcpy(imageData, [jpegImageData bytes], jpegImageSize);

//針對jpeg就解碼
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imageData, jpegImageSize, NULL);
CGImageRef image = CGImageCreateWithJPEGDataProvider(provider, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);

//初始化貼圖,解析度用iPad
CCTexture2D * tex = [[CCTexture2D alloc] initWithCGImage:image resolutionType:kCCResolutioniPad];
free(imageData);
CGImageRelease(image);

//這樣就可以建sprite了
CCSprite *sprite = [CCSprite spriteWithTexture:tex];



參考網址:
Cocos2d screenShot
CGDataProvider Reference
JPEG Header Format
通过Quartz+Core Image读取JPEG图像的二进制位图
How exactly to make a CGImageRef from an image on disk
CCTexture2D errors in adding images
Using CGDataProviderCreateWithData callback

2013年3月10日 星期日

iOS開發筆記 -UDP socket使用AsyncUDPSocket

在iOS上有個好用的library:CocoaAsyncSocket。我想用的是UDP socket,所以選了AsyncUdpSocket。

先建好一個project,將AsyncUdpSocket.h及AsyncUdpSocket.m複製過去。記得加入CFNetwork.framework

這邊有個地方要注意是,AsyncUdpSocket用的是ARC,若專案沒有設定ARC,則要加入編譯條件:

在項目target -> build phases -> compile sources -> AsyncUdpSocket文件後面加入-fobjc-arc,這是為了使編譯器compile-的時候將此文件在arc的條件下編譯。

新增一個要用到的檔案,例如這邊是example

#import <Foundation/Foundation.h>
#import "AsyncUdpSocket.h"

#define DEFAULT_UDP_TIMEOUT 10;

@interface example : NSObject<AsyncUdpSocketDelegate> {
 
}


-(IBAction)sendData:(id)sender;


@end

#import "example.h"

@interface example() {
   AsyncUdpSocket * __udpSocket;
}

- (void)initialSocket;

@end

@implementation example

#DEFAULT_UDP_TIMEOUT 3000.0f

#DEFAULT_UDP_TAG 1

- (id)init

{
    self = [super init];
    if (self != nil) {
       Byte *byteArray = (Byte*)malloc(sizeof(Byte)*5);
       NSData *data = [NSData dataWithBytes:byteArray length:5];
       [self initialSocket:data];
    }
    return self;
}

-(IBAction)sendData:(NSData*)data sender:(id)sender
{
    [__udpSocket sendData:data withTimeout:DEFAULT_UDP_TIMEOUT tag:DEFAULT_UDP_TAG]; //TAG要一樣,才能在同個頻道
}


- (void)initialSocket:(NSData*)data {
    //初始化udp packet
    __udpSocket = [[AsyncUdpSocket alloc] initWithDelegate:self];
    
    NSError *error = nil;
    
    if (![__udpSocket isConnected]) {
        
        
        ConfigObject *config = [ConfigObject sharedConfigObject];
        
        NSError *error;
        if( [__udpSocket connectToHost:config.ip onPort:config.port error:&error] ) {
            CCLOG(@"Ready");
            
            //觸發回應
            [self sendData:data sender:nil];
            
        }
        else
            CCLOG(@"Fail: %@",error);
    }
}


//以下是AsyncUdpSocketDelegate的function
#pragma mark udp socket

- (void)onUdpSocket:(AsyncUdpSocket *)sock didSendDataWithTag:(long)tag
{
     NSLog(@"data: %@",);
}

- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error
{
// You could add checks here
}

- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock
     didReceiveData:(NSData *)data
            withTag:(long)tag
           fromHost:(NSString *)host
               port:(UInt16)port
{
//    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     NSLog(@"msg: %@",data);

     [__udpSocket receiveWithTimeout:DEFAULT_UDP_TIMEOUT tag:DEFAULT_UDP_TAG];
return YES; //這行一定要有,否則就會到此結束

}


@end


要傳資料就可以用sendData即可

參考網址:
IOS And AsyncUDPSocket - Tutorial?
CocoaAsyncSocket
iPhone 發送UDP廣播並接收資料
iOS AsyncUdpSocket使用简介
iPhone的Socket编程使用开源代码之AsyncSocket
详解iPhone 下AsyncSocket网络库编程