2015年11月24日 星期二

(CS193p) Developing Applications for IOS 2013 筆記 Lecture2 Xcode5

Lecture2 Xcode5

這禮拜繼續講解他的紙牌遊戲

一、 Desk

1. - (void)addCard:(*Card)card atTop:(BOOL)atTop
這個method的名稱為addCard atTop
extra arguments的穿插方式比較特別
注意Objective-C中method名稱不可重複

2. NSMutableArray
NSArray通常不會改變,而MutableArray可以動態加入或刪除物件,類似Java的ArrayList

3. Lasy Instantiation
MutableArray的getter需要覆寫,如果getter中只有return _property,將永遠只return nil,因為MutableArray從來沒有被allocate過。所以應該把getter改成:
- (NSMutableArray *)cards
{
    if(!_cards)
      _cards = [[NSMutableArray alloc] init];
    return _cards;

}

4. 補充unsigned
unsigned修飾詞代表非負數,直接寫unsigned等於unsigned int非負整數

5. Paul教授補充
Q:為什麼不用NSNumber? 
A:因為NSNumber是Object,這裡只是個簡單的local變數,通常需要再多個method間傳遞時才會用Object

二、PlayingCard

繼承自Card,用來製造撲克牌

1. Properties
suit:花色  rank:點數

2. NSUInteger
= unsigned int,在iPhone4(32-bit)和iPhone5(64-bit)上長度不同

3. @
@在Object-C裡面代表Object
而String物件(NSString)需要表達成@""
@[]代表Object Array

4.Override
覆寫contents的getter,return花色和點數的String
覆寫suit的getter,如果suit=nil,return "?"
覆寫suit的setter,只能輸入♠,♥,♣,
注意!同時Override setter和getter時會出現錯誤,一定要在前面加上:
@synthesize myProperty = _myProperty;

5. Class Method
似乎有點像Java的static method,呼叫時是用[MyClass calssMethod]
method前面不是"-",而是"+"
send to class, not send to instance of an Object
use it when you're creating things
Paul在這邊這樣用不是為了效能,是為了可讀性,因為每次使用這些method時都要產生一次String array

三、 PlayingCardDeck

繼承自Deck,只有一個method,目的是初始化52張撲克牌。

1.init method
只能呼叫一次
包含alloc
always return self

2. instancetype
IOS7加入,代表和目前class相同的class type

3. self = [super init]
必須先呼叫super initializer
initializer 不能 initialize時會 return nil,以此來檢查是否有正常initialize

四、Xcode

xcode的基本操作,也是這周的作業,在投影片裡面有很詳細的步驟。




2015年11月23日 星期一

(CS193p) Developing Applications for IOS 2013 筆記 Lecture1

很久沒碰IOS了,決定重新學起
IOS經典課程 Stanford CS193p Developing Applications for IOS
是史丹佛大學在iTunesU上面的公開課
有完整的課程影片、字幕和投影片pdf檔
但在2014年後的課程都改採用Swift了
所以還是回去看2013的IOS7 in Objective-C
這是我邊看邊寫的筆記,會這著課程的堂數寫


一、IOS系統架構


很快速的介紹系統架構,由下而上分別為4層:

Core OS
Base on Unix Kernel
BFD-based mock
在這個課程不太會用到
Core Services
IOS是基於C寫成的,但是Objective-C是物件導向語言,所以在這裡實現OO的language tools還有Multithreading。另外還有GPS定位等東西
Media
就Media
Cocoa Touch
實現IOS的UI。值得一題的是Cocoa touch是從Mac OS搬過來的,所以也能在Mac OS上使用,而且有30年以上的歷史,比我還老。
這個課程將集中在Media和Cocoa Touch層


二、Platform Components

工具(IDE):Xcode5 (我用的是Xcode7)
語言     :Objective-C
Frameworks: Foundation(Array,Dictionries...), UIKit
設計模式 :MVC 相當重要的觀念,下面會繼續介紹


三、MVC模式


Model View Controller,這個模式關乎於你程式中classes的分類,Class應分為三類:

Model:What of your program. 負責程式的運算、邏輯等
Controller:How your Model is presented to user. 負責Model和View的溝通
View:負責顯示UI

MVC的溝通形式:
1. Controller -> Model / View

Controller 可以直接talk to Model or View


2. Model <-> View
model 和view必須是完全獨立的,絕對不能讓他們直接溝通


3. View -> Controller



A)View可以跟controller溝通,但是View並不清楚它將跟哪個controller溝通。

像是User在View上按下某個Button,然後View將觸發一個Action,這個Action將通知 Controller中的某個target。
(圖示:action是箭,target是靶。按下button後箭射向靶,View所知道的就只有"我發射了Action")

B)Protocol
這是一個物件導項的觀念。View有時候會遇到較複雜的問題,教授在這裡分出3項概念:Will,Should,Did
以一個Scroller View為例:
當User按下螢幕時它會滑動嗎?(Will)
這時後該允許滑動嗎?(Should)
已經滑動到某個點?(Did)
但是View不會知道這些問題的答案,它會把這些問題委派(delegate)給controller,讓controller回答。

C)Data source
Views不該擁有它們所顯示的data,data應存在於Model
所以Controller還有一種委派的形式:Data source
以音樂列表為例:User開啟音樂列表,此時View就會問Controller總共有多少歌?
Controller從Model得知有10,000首,回覆View,View便創造出10,000的空間。
User往下滑,這時View就告訴Controller下滑到哪裡,Controller就以此向Model要資料,像:給我第150條起的10項條目

4. Model -> Controller
A)Notification & KYO(key value object)
model一樣不會直接跟Controller溝通
model的data改變時,會發出一個廣播(broadcast),而controller中的接收器會接收這個廣播,並決定是否要處理。Controller可以收到廣播後立刻向Model要求改變的資料。


四、Objective-C

Paul教授的講解不是從Hello World開始,而是一個紙牌遊戲,這禮拜實作的Class是"Card"。

1. Objective-C 是基於C的,所以C的code在Objective-C上也能執行

2. implementation file & header file
header file: public API 副檔名是.h
implementation file: private API 副檔名是.m

3. Properties
就是實例變數(Instance variable)
每個property都需要有getter和setter,在header宣告完後Objective-C會自動產生setter和getter,IDE上不會顯示出來,但是仍要記得它們的存在。
nonatomic代表不能同時有多個線程(Thread)set這個property
getter=isChosen,因為這邊chosen的getter會自動命名為"chosen",但通常我們在使用boolean時會希望它叫做"isChosen",所以加上這段重新命名
private property可以加在implementation file的 @interface class名()@end 之間

4. @synthesize contents = _contents
代表contents這個property在這裡的名字是"_contents"

5. Automatic reference counting
類似於java的garbage collection但是更為強大。
Objective-C所有物件都存在於heap
Objective-C會自動處理物件的free和allocate
property的修飾詞strong / weak 關乎於IOS如何處理Object的Memory
strong: Objective-C 會在所有指向此物件的strong pointer消失後free掉這個物件
weak: Objective-C 會在所有指向此物件的strong pointer消失後free掉這個物件,並把這個pointer設成nil。(在Objective-C送訊息給nil pointer不會造成crash)
不存在heap中的property不需要strong/weak修飾詞,像是BOOL

6. 初始值
所有的properties的初始值都是0,而pointer的初始值是nil

7. 程式碼翻譯(to Java)
Objective-C      [card.contents isEqualToString:self.contents]
Java             card.contents.equals(this.contents)

Objective-C      for(Card *card in otherCards)
Java             for(Card card : otherCards)

2015年10月21日 星期三

安裝MariaDB與phpMyAdmin (XAMPP)

最近想把原本的MySQL資料庫換成MariaDB
維基百科-MariaDB
還好包含PHP,Apache,MySQL的懶人包:XAMPP 在5.5.30版之後也將MySQL換為MariaDB了
XAMPP官網下載最新版的安裝檔
支援Windows,Mac,Linux三種平台
安裝包裡面還有FileZilla和Perl等東西,可以自行決定要不要安裝
安裝完後開啟XAMPP control panel,然後開啟Apache和MySQL server(雖然已經換成MariaDB,上面仍然是寫MySQL)
再來到瀏覽器進入 127.0.0.1/phpmyadmin 即可使用

寫到這裡發生一個問題:
phpMyAdmin在MariaDB 10.0.21新增使用者時會出現error:
      #1065 - Query was empty
      使用者不在權限表上
好在已經有人在GitHub上反映這個問題
而且已經得到解決
你可以去下載最新的phpMyAdmin或是照以下的步驟手動解決
打開xampp\phpMyAdmin\libraries 中的server_privileges.lib.php
加入以下綠色的code(4915行開始)
修改完再重開MariaDB Server就可正常執行

if (PMA_MYSQL_INT_VERSION >= 50507
         && PMA_Util::getServerType() == 'MySQL'
         && isset($_REQUEST['authentication_plugin'])
     ) {
         $create_user_stmt .= ' IDENTIFIED WITH '
             . $_REQUEST['authentication_plugin'];
     }
     if (PMA_MYSQL_INT_VERSION >= 50707
         && PMA_Util::getServerType() == 'MySQL'
         && strpos($create_user_stmt, '%') !== false
     ) {
         $create_user_stmt = str_replace(
 @@ -4944,7 +4946,9 @@ function PMA_getSqlQueriesForDisplayAndAddUser($username, $hostname, $password)
     );
     $real_sql_query = $sql_query = $sql_query_stmt;

     if (PMA_MYSQL_INT_VERSION < 50707) {
         || PMA_Util::getServerType() != 'MySQL'
     )


別忘了phpMyAdmin預設是不用密碼的裸奔狀態
為root加入密碼
刪除那些不需密碼的root
並修改xampp\php\php.ini

/* Authentication type and info */
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = '';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['AllowNoPassword'] = false;
$cfg['Lang'] = '';

2015年9月15日 星期二

Parse : 建立Cloud code (Mac OS)

Cloud code 顧名思義就是直接在Parse的資料庫執行自訂的code
code必須由javaScript寫成
因為Parse官方的中文說明步驟有點怪,特別做了這個筆記

1. 安裝Parse Command Line Tool

    Mac或Linux只要在終端機下一行指令就能安裝:
    curl -s https://www.parse.com/downloads/cloud_code/installer.sh | sudo /bin/bash
  
  Windows請看這裡

2. 連結Parse帳號

    輸入指令: parse new
    然後會要求你輸入帳號(Email)和密碼,如果是用google或fb帳號登入的,記得到帳戶那邊設定密碼
    接著選則project或新建project
    最後輸入本機目錄名稱(Cloud Code的檔案會儲存在 /Users/使用者名稱/本機目錄名稱)

3. 上傳Cloud Code

    打開你的Cloud code資料夾可以看到裡面有Cloud和Public兩個子資料夾
    Cloud裡面有一個main.js的Hello world示範程式
    用XCode就可以修改它
    用cd指令跳到Cloud code資料夾
    例: cd test
    然後下parse deploy指令就可同步到你的Parse帳號(此時可能會再次要求帳號密碼)

2015年8月25日 星期二

Jackcess 無法修改Row的error

有時在update row的時後會跳出unsupported collating sort order或類似的error
似乎是資料庫用了Jackcess不支援的sort格式導致的
作者也表示不想花太多時間去支援各種sort格式...
所以必須用Access修改資料庫的排序法才行
已下用Access 2003示範,Acess 2007也可以,只是按紐位置不同而已

1. 打開你的資料庫

2. 工具 -> 選項

3. 一般 -> 新的資料庫排序 -> 選擇「一般」-> 確定
 

4. 工具 -> 資料庫公用程式 -> 壓縮及修復資料庫

再次用Jackcess開啟時就可以正常修改了喔

2015年6月4日 星期四

Calendar的陷阱 : 24小時or12小時制?

Java的Calendar是有分12小時制和24小時制的
之前一直以為他預設24小時制一直鬼打牆

Calendar.HOUR指的是12小時制的小時,如:
calendar.set(Calendar.HOUR, 5);

HOUR_OF_DAY才是24小時制的
如果給Calendar.HOUR超過12的數值日期可能會跑掉

正確用法(假設要設晚上8點):

24小時制
calendar.set(Calendar.HOUR_OF_DAY, 20);

12小時制
calendar.set(Calendar.AM_PM, Calendar.PM);
calendar.set(Calendar.HOUR_OF_DAY, 8);

也可以用calendar.get(Calendar.AM_PM)取得現在是上午或下午
calendar.get(Calendar.AM_PM)回傳整數1或0
0表AM 1表PM

2015年5月31日 星期日

在Goole play books上架書籍(二) - Word轉Epub

epub是一種國際標準的電子書格式
Google Play Books只支援pdf和epub兩種格式
推薦使用epub
詳見為基百科http://zh.wikipedia.org/wiki/EPUB

以下說明如何從word檔轉換為epub格式
並在Google Play Books上架
這是轉好的成品: 逍遙遊

1.  下載並安裝電子書神器: calibre http://calibre-ebook.com/download
calibre可以幫你開啟、轉換、整理電子書
免費,而且支援Linux、Mac、Windows
還有內建繁體中文,比較可惜的點是不支援中文直讀

2. 如果calibre打開時是英文,點左上方的Preference -> Look And Feel -> Choose Language
選擇Traditional Chinese 然後點Apply,重開calibre後介面就會變中文了



3. 點左上角的"加入書籍",加入要轉換的書籍

4. 在書籍上點右鍵->轉換書籍->個別轉換
    將輸出格式改為epub,輸入書名、作者等資訊,也可以加入書籍的封面


5.  calibre預設檔案若超過260kb就會自動切割,如果你想要手動切割的話(本次試範為手動)
     在epub輸出頁面,把"分割大於此項的檔案"調大
     調整完後按確定,等後轉換完成


製作目錄: 如果你的word檔本身沒有設定目錄,或者calibre無法精準偵測你的目錄,就要自己手動增加。

6. 在書籍上點右鍵-> Edit book

7. 你的文章儲存在index.html中,如果沒有做第5步驟,可能會被切為多個檔案



8~12步是在手動分章節,不需要的話可以跳過

8. 先新增一個章節
    檔案 -> New file -> 輸入"章節名稱.html"  -> 確定


9. 剪貼內容
    點兩下index.html,把第一章的內容剪下

10. 然後貼到第一章的檔案(貼在<body> </body> 之間)


11.  複製格式
       將 <link href="stylesheet.css" rel="stylesheet" type="text/css"/>
<link href="page_styles.css" rel="stylesheet" type="text/css"/>
       複製到第一章的檔案中(<head>和</head>之間)


12. 重複8~11的步驟,完成所有章節

13. 編輯目錄
      Tools -> 目錄 -> Edit Table of Contents ->建立新的項目




14.  選擇章節檔案並輸入章節名稱 -> 確定

如果沒有分割章節也可以用滑鼠直接指定章節位置
15.以此類推加入所有章節,完成後別忘記儲存!


先別急著上架,在上傳epub檔案時Google會對你的檔案進行格式驗證
不符合規定的epub檔無法上傳
為了節省時間還是先自己檢測吧
用google指定的檢測工具EpubCheck

線上檢測工具 : EPUB Validator http://validator.idpf.org/

檢測軟體 : pagina EPUB-Checker(推薦) http://www.pagina-online.de/produkte/epub-checker/

檢查無誤後就可以上傳囉

2015年5月28日 星期四

Swing: 在JTable用滑鼠右鍵選擇row

JTable預設用滑鼠左鍵選擇row
那如果要用右鍵選擇並執行其他動作呢?

//  BUTTON3代表滑鼠右鍵
if(evt.getButton() == MouseEvent.BUTTON3){
            Point point = evt.getPoint();
            int row = table.rowAtPoint(point);
           
            ListSelectionModel listModel = table.getSelectionModel();
            listModel.setSelectionInterval(row, row);
            //要執行的動作
}

另外,使用ListSelectionModel的clearSelection()可以清除已選擇的row

2015年5月27日 星期三

在phpMyAdmin新增組合鍵(Composite Key)

SQL中可以設定多個欄位組合成一個主鍵,稱為組合鍵(Composite Key)

用SQL與法可以這樣加入:
CONSTRAINT name_of_primary_key PRIMARY KEY (column1, column2)
 
在phpMyAdmin也可以很方便的設定:
 
1.點"索引"

 
2.增加一個新的索引


3.索引類型選PRIMARY
   然後新增欄位,再選擇要設定為組合鍵的欄位





2015年5月15日 星期五

在Android Studio中新增assets資料夾

在專案上點右鍵-> New -> Folder -> Assets Folder


assets資料夾在硬碟中的位置:
  專案\app\src\main\assets

2015年5月6日 星期三

取得Date或Calendar中的年、月、日

Java在sdk 1.1後刪除了 Date和 Calendar中的 getDay等function
改由 Calendar.get(int field) 取代

範例:

        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day = calendar.get(Calendar.DATE);
        int month = calendar.get(Calendar.MONTH) + 1;
        int year = calendar.get(Calendar.YEAR);

因為calendar中的月份是由0算起 (也就是說如果現在是一月,month輸出為0)
所以上方的month我讓他加1

同樣,Calendar中的setYear等function也被取消了,可用Calendar.set(field, value)或Calendar.set(year, month, date)替代

範例:

        calendar.set(Calendar.YEAR, 2015);

2015年3月16日 星期一

Jackcess(用來連接Access的Java Library) : (二) 開啟Access檔案

最基本的開啟方法:

Database db = DatabaseBuilder.open(new File("mydb.mdb"));

是不是很簡單呢?
但是如果要應付不同的需求就得增加點變化了

Q1: 如果我的Access資料庫有密碼呢?

確認一下你的專案是否有加入jackcess-encrypt(詳見上一篇)
然後將上面的程式碼改成這樣:

File dbFile = new File("mydb.mdb");
CryptCodecProvider codec = new CryptCodecProvider("my password");
Database db = new DatabaseBuilder(dbFile).setCodecProvider(codec).open();

Q2: Access97打不開!

由於Jackcess目前只支援Access 97 read only
所以開啟97的mdb時必須聲明唯讀

Database db = new DatabaseBuilder(dbFile).setReadOnly(true).open();

Q3: 讀取出來的資料變成亂碼怎麼辦?

像我的mdb檔中文字是用big5編碼
讀出來全是亂碼
Jackcess一樣提供了編碼解決方案:

Database db = new DatabaseBuilder(dbFile).setCharset(Charset.forName("big5")).open();

2015年3月12日 星期四

Jackcess(用來連接Access的Java Library) : (一) 將Jackcess library加入專案

因為工作的關係需要將一個古老的Access 97資料庫轉換到MySQL
但大部分的資料庫library都不支持Access 97
最後終於找到這個 Jackcess
支援Access 2000-2010 read/write
不過Access 97只有read only
以下將介紹如何把Jackcess加入你的專案

1.
先下載 jackcess-x.x.x.jar 並加入專案

2.
使用前必須先加入一些必要的Library
Jackcess 2.0.8版需要的library如下
commons-lang-2.6.jar
commons-logging-1.2.jar
相關內容也寫在:Project Dependencies
注意:如果用commons-lang 3.x可能會出現錯誤

3.
如果你的Access資料庫有密碼,那就得再加入Jackcess Encrypt
下載並加入以下library:
jackcess-encrypt-x.x.x.jar
bcprov-jdk15

使用方法在官網有簡要的說明:jackcess cookbook
我接下來也會再作相關的筆記

Jackcess(用來連接Access的Java Library) : (二) 開啟Access檔案

2015年3月6日 星期五

NetBeans中的自動補齊(Java)

Tools -> Options -> Code Completion
Language 選擇 Java -> 將 Auto Popup on Typing Any Java Identifier Part 打勾