https://sites.google.com/site/chengshixuexipingtai/android/android-fragment
Android 上的界面展示都是通過 Activity 實現的。
但是 Activity 也有它的局限性,同樣的界面在手機上顯示可能很好看,在平板上就未必了,因為平板的屏幕非常大,手機的界面放在平板上可能會有過分被拉長、控件間距過大等情況。這個時候更好的體驗效果是在 Activity 中嵌入「小 Activity」,然後每個「小 Activity」又可以擁有自己的佈局。因此,我們今天的主角 Fragment 登場了。
Fragment初探
為了讓界面可以在平板上更好地展示,Android 在 3.0 版本引入了 Fragment (碎片) 功能,它非常類似於 Activity,可以像 Activity 一樣包含佈局。Fragment 通常是嵌套在 Activity 中使用的,現在想像這種場景:
有兩個 Fragment,
Fragment 1 包含了一個 ListView,每行顯示一本書的標題。
Fragment 2 包含了 TextView 和 ImageView,來顯示書的詳細內容和圖片。
如果現在程序運行豎屏模式的平板或手機上,Fragment 1 可能嵌入在一個 Activity 中,而Fragment 2 可能嵌入在另一個 Activity 中,如下圖所示:
而如果現在程序運行在橫屏模式的平板上,兩個 Fragment 就可以嵌入在同一個 Activity 中了,如下圖所示:
由此可以看出,使用 Fragment 可以讓我們更加充分地利用平板的屏幕空間,下面我們一起來探究下如何使用 Fragment。
首先需要注意,Fragment 是在 3.0 版本引入的,如果你使用的是 3.0 之前的系統,需要先導入android-support-v4 的 jar包才能使用 Fragment 功能。
新建一個項目叫做 Fragments,然後在 layout 文件夾下新建一個名為 fragment1.xml 的佈局文件:
詳請閱 https://sites.google.com/site/chengshixuexipingtai/android/android-fragment
Display Zoom (螢幕縮放) 是 Apple 推出 iPhone 6 時提供的新功能之一
Display Zoom (螢幕縮放)
這功能是在推出iPhone 6(解析度1334x750)時提供的新功能之一,
在「設定」的「螢幕顯示與亮度」的「螢幕縮放」,
選擇 iPhone 的顯示畫面。「放大」會顯示較大的控制項目,但「標準」模式可顯示更多內容。
若設定「放大」後,就可以用 iPhone 5(解析度1136x640)為基底來放大,表示所有 app 的圖示,按鍵及畫面等都比原生的視圖設置變得更大,然而因為所有東西都被放大到了 1334x750,反而會顯得有一些模糊感,這個功能是為那些上了年紀或者是希望閱讀更大的顯示內容的用戶而設的。
以上都是字面上的解釋,也是要來實際操練才會知道這個功能對 app 有怎樣的影響:
https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E6%95%99%E5%AE%A4/d825f1809828
這功能是在推出iPhone 6(解析度1334x750)時提供的新功能之一,
在「設定」的「螢幕顯示與亮度」的「螢幕縮放」,
選擇 iPhone 的顯示畫面。「放大」會顯示較大的控制項目,但「標準」模式可顯示更多內容。
若設定「放大」後,就可以用 iPhone 5(解析度1136x640)為基底來放大,表示所有 app 的圖示,按鍵及畫面等都比原生的視圖設置變得更大,然而因為所有東西都被放大到了 1334x750,反而會顯得有一些模糊感,這個功能是為那些上了年紀或者是希望閱讀更大的顯示內容的用戶而設的。
以上都是字面上的解釋,也是要來實際操練才會知道這個功能對 app 有怎樣的影響:
https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E6%95%99%E5%AE%A4/d825f1809828
Auto Layout 入門教學
Apple 官方文件:https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html
https://www.appcoda.com.tw/introduction-auto-layout/
Auto Layout 是一個以約束條件為基礎的佈局系統,它可以讓開發者建立一個可以因應不同螢幕尺寸與裝置(device)方向而調整的自適應介面(adaptive interface)
Align – 建立一個對齊的約束條件,例如對齊兩個視圖的左側。
Pin – 建立間距約束條件,例如定義一個UI控制的寬度。
Issues – 解決佈局問題。
Resizing – 指定尺寸調整後影響約束條件的方式為何。
首先,以 Single View Application iOS App 模板來設定一個新的專案。在專案選項的 Device,選擇 iPhone,然後儲存專案,然後打開 Storyboard。你會注意到在右下角區域有一個選單。在選單的按鈕是跟 Auto Layout 有關,你可以用它來處理對齊(alignment),尺寸(sizing)、間距(spaceing)以及約束條件(constraint)問題。
自動佈局是一個很神奇的工具,它能做到以之前的技術連作夢都無法辦到的事情。對於在建立視圖間的交互關聯中其邊緣狀況(edge case)的處理,Auto Layout充分展現了強大的力量。Auto Layout 還能夠與許多 Apple 中最令人興奮的應用程式介面(APIs)相容,其中包括了動畫(animation),移動特效(motion effect)以及 sprite。
我知道有許多討厭 Auto Layout 的開發者,也許是這是一個新的技術,或者第一次使用時感到很難使用。不管你是否相信,倘若你習慣它,它會變成最棒的工具之一,沒有它的話,反而開發不了 App 了。
除了 Auto Layout 外,Apple 讓開發者可以更彈性使用 Control 加上拖曳來設定 Auto Layout,你只要從任何視圖按住 control 鍵不放,然後拖曳來設定相互間的約束條件即可。當你將滑鼠放開,它會呈現一個相關約束條件列表來讓你選取。
在視圖中設定完約束條件之後,約束線(constraint line)不是以橘色就是藍色來呈現。橘色約束線表示目前的約束條件不足,你必須要去修正它。
出現藍色的約束條件,表示你的佈局已經正確的設定,沒有其他模糊不清的情況。
有時候在約束條件建立後,介面建構器大綱(Interface Builder outline)視圖會顯示一個揭示箭頭。這個紅色的箭頭指出還有些衝突或者不清楚的情況。點擊這個揭示箭頭,你會見到一串問題。這些問題是以場景(scene)為基礎來顯示。一般會出現像是約束條件不足,約束條件衝突以及視圖錯位的問題。
在尺寸檢閱器(Size Inspector),你可以見到所有已經加入的約束條件清單,這些約束條件出現在稱作「Constraints」的區塊中。
除了尺寸檢閱器視圖以外,這些約束條件也會出現在介面建構器大綱內的相對應視圖下。
https://www.appcoda.com.tw/introduction-auto-layout/
Auto Layout 是一個以約束條件為基礎的佈局系統,它可以讓開發者建立一個可以因應不同螢幕尺寸與裝置(device)方向而調整的自適應介面(adaptive interface)
Align – 建立一個對齊的約束條件,例如對齊兩個視圖的左側。
Pin – 建立間距約束條件,例如定義一個UI控制的寬度。
Issues – 解決佈局問題。
Resizing – 指定尺寸調整後影響約束條件的方式為何。
首先,以 Single View Application iOS App 模板來設定一個新的專案。在專案選項的 Device,選擇 iPhone,然後儲存專案,然後打開 Storyboard。你會注意到在右下角區域有一個選單。在選單的按鈕是跟 Auto Layout 有關,你可以用它來處理對齊(alignment),尺寸(sizing)、間距(spaceing)以及約束條件(constraint)問題。
自動佈局是一個很神奇的工具,它能做到以之前的技術連作夢都無法辦到的事情。對於在建立視圖間的交互關聯中其邊緣狀況(edge case)的處理,Auto Layout充分展現了強大的力量。Auto Layout 還能夠與許多 Apple 中最令人興奮的應用程式介面(APIs)相容,其中包括了動畫(animation),移動特效(motion effect)以及 sprite。
我知道有許多討厭 Auto Layout 的開發者,也許是這是一個新的技術,或者第一次使用時感到很難使用。不管你是否相信,倘若你習慣它,它會變成最棒的工具之一,沒有它的話,反而開發不了 App 了。
除了 Auto Layout 外,Apple 讓開發者可以更彈性使用 Control 加上拖曳來設定 Auto Layout,你只要從任何視圖按住 control 鍵不放,然後拖曳來設定相互間的約束條件即可。當你將滑鼠放開,它會呈現一個相關約束條件列表來讓你選取。
在視圖中設定完約束條件之後,約束線(constraint line)不是以橘色就是藍色來呈現。橘色約束線表示目前的約束條件不足,你必須要去修正它。
出現藍色的約束條件,表示你的佈局已經正確的設定,沒有其他模糊不清的情況。
有時候在約束條件建立後,介面建構器大綱(Interface Builder outline)視圖會顯示一個揭示箭頭。這個紅色的箭頭指出還有些衝突或者不清楚的情況。點擊這個揭示箭頭,你會見到一串問題。這些問題是以場景(scene)為基礎來顯示。一般會出現像是約束條件不足,約束條件衝突以及視圖錯位的問題。
在尺寸檢閱器(Size Inspector),你可以見到所有已經加入的約束條件清單,這些約束條件出現在稱作「Constraints」的區塊中。
除了尺寸檢閱器視圖以外,這些約束條件也會出現在介面建構器大綱內的相對應視圖下。
Design Guidelines 設計指南
https://blog.akanelee.me/categories/ui-%e9%9b%9c%e8%ab%87/
UI 設計師要不要懂技術:https://blog.akanelee.me/posts/260026-designers-dont-understand-technology/
企劃=告訴你為什麼要 PS 照片、動手術的人。
PM=協調開刀時間、叫各單位做事的人。
設計師=負責 PS 照片、提出理想(妄想)的人。
RD=執行醫美手術的醫生,負責把理想變成現實的人。
曾聽過 RD 抱怨:「幹!說時程太趕不蓋 1 樓了,直接蓋 2 樓和 3 樓,是要我綁多少氣球演天外奇蹟!」
怎麼和 RD 配合製作 UI Animation (動畫):https://blog.akanelee.me/posts/290551-and-rd-tie-how-to-make-ui-animation/
Apple Human Interface Guidelines
https://developer.apple.com/design/human-interface-guidelines/
https://medium.com/@penny40727/925db5b5a595
https://blog.akanelee.me/posts/192859-how-to-read-guidelineios-1/
UI 設計師要不要懂技術:https://blog.akanelee.me/posts/260026-designers-dont-understand-technology/
企劃=告訴你為什麼要 PS 照片、動手術的人。
PM=協調開刀時間、叫各單位做事的人。
設計師=負責 PS 照片、提出理想(妄想)的人。
RD=執行醫美手術的醫生,負責把理想變成現實的人。
曾聽過 RD 抱怨:「幹!說時程太趕不蓋 1 樓了,直接蓋 2 樓和 3 樓,是要我綁多少氣球演天外奇蹟!」
怎麼和 RD 配合製作 UI Animation (動畫):https://blog.akanelee.me/posts/290551-and-rd-tie-how-to-make-ui-animation/
Apple Human Interface Guidelines
https://developer.apple.com/design/human-interface-guidelines/
https://medium.com/@penny40727/925db5b5a595
https://blog.akanelee.me/posts/192859-how-to-read-guidelineios-1/
什麼是 Android NDK
http://www.powenko.com/wordpress/%E4%BB%80%E9%BA%BC%E6%98%AFandroid-ndk/
Android NDK (Native Development Kit) 簡化工作與機器底層的程式碼。並且可以與CPU(ARM)和繪圖晶片做溝通。它的目的是幫助您創建 Lib,你可以把它想成是 Android C 的函式庫 Lib。
大多數的開發者都是使用 Android SDK 來設計應用程式,它是一個以 JAVA 為基礎的程式語言,但是在開發大型專案和較複雜的應用程式時,會因為 JAVA 的速度或者與系統底層溝通的因素,會遇到很多問題。
如果要邁向頂尖的 Android 開發者,很多時候是需要使用 C 語言來開發,尤其是 Android 系統底層的功能,真的很難用 JAVA 寫的出來,所以要對整個 Android 系統深度了解,還是需要C 語言。
Android NDK (Native Development Kit) 簡化工作與機器底層的程式碼。並且可以與CPU(ARM)和繪圖晶片做溝通。它的目的是幫助您創建 Lib,你可以把它想成是 Android C 的函式庫 Lib。
大多數的開發者都是使用 Android SDK 來設計應用程式,它是一個以 JAVA 為基礎的程式語言,但是在開發大型專案和較複雜的應用程式時,會因為 JAVA 的速度或者與系統底層溝通的因素,會遇到很多問題。
如果要邁向頂尖的 Android 開發者,很多時候是需要使用 C 語言來開發,尤其是 Android 系統底層的功能,真的很難用 JAVA 寫的出來,所以要對整個 Android 系統深度了解,還是需要C 語言。
| 比較項目 | Android SDK | Android NDK |
| 程式語言 | JAVA | C |
| 執行速度 | 慢 | 快 |
| 與底層Linux 溝通 如 ls, mkdir 等Linux 指令 | 沒有相對的API | 可 |
| 直接呼叫linux driver | 沒有直接的API,需要透過HAL 的寫法,較為複雜 | 可 |
| Users Interfae 使用者操作介面 | 有 | 需要依賴SDK |
| GPS, 撥號, 地圖 | 有 | 需要依賴SDK |
| 跨平台開發 | 只有在Android 平台上 | 可以跨平台Android, iOS, Windows Phone等 |
| 開發環境 | Eclipse 開發環境 | 無,需透過指令 Terminal |
Architecture: MVP, MVC, MVVM
https://dotblogs.com.tw/regionbbs/2011/09/29/compare_to_mvp_mvc_mvvm
最近 MVC (Model-View-Controller) 和 MVVM (Model-View-ViewModel) 在微軟圈成為顯學,ASP.NET MVC 和 WPF 的 Prism (MVVM Framework) 功不可沒,MVC 和 MVVM 在概念上都是基於分層的,將呈現 (presentation) 與資料 (data) 分開的設計架構,M 和 V 基本上不是問題,但將這兩個整合的中間這層可就有很多的學問,另外,除了 MVC 和 MVVM 外,還有一個叫做 MVP (Model-View-Presenter) 的架構,這三個的設計概念非常類似,很容易會讓人傻傻分不清楚 ...
我們先來看各個架構的設計原則好了。
首先是 MVC,顧名思義,MVC 是將 Model, View 和 Controller 分離,讓彼此的職責 (responsibility) 能夠明確的分開,這樣不論是改 M, V 還是 C,都可以確保另外兩層可不用做任何修改,同時這樣的分層也可以加強程式的可測試性 (testability),View 和 Model 基本上是相關的,但它們並不會有直接的相依關係,而是由 Controller 去決定 Model 產生的資料,然後丟給 View 去做呈現,也就是說,Controller 是 Model 和 View 之間的協調者 (coordinator),View 和 Model 不能直接溝通,以確保責任的分離。而 Controller 可以只是一個繫結 Model 和 View 的小類別,也可以是大到包含 Workflow, Enterprise Services 或是做為外部系統的 Proxy Services 等的邏輯系統,MVC 各元件是可以分離的組件,也可以是分離的系統 (當然要設計一些機制在相互溝通)。
再來是 MVVM,MVVM 的架構一樣是 M, V 分離,但中間是以 VM (ViewModel) 來串接,這個 ViewModel 比較像是 View 的一個代理程式,它負責直接對 Model 做溝通,而 View 可以透過一些機制 (ex: Events, Two-way Databindings, ...) 來和 ViewModel 溝通以取得資料或將資料拋給 Model 做存取等工作,ViewModel 也可以作為和外部系統的代理程式,例如 Web Service 或是 REST Service 或是 Enterprise Services 等等,不過它和 MVC 不同的地方,就是 ViewModel 和 View 的黏合度比較高,因為 View 必須要透過 ViewModel 才可以取得 Model,而 ViewModel 又必須要處理來自 View 的通知訊息,所以雖然職責一樣分明,但是卻不像 MVC 那樣可以擴展到整個系統元件都能用。如果 MVVM 要和 MVP 比較的話,MVVM 會比 MVP 更靈活一點。
接著是 MVP,MVP 一樣也是職責分明,且 Model 與 View 分離的架構,但是這個 P (Presenter) 和 ViewModel 就很類似,不過就如同 Presenter (主持人) 這個字所代表的意義,所有主控 View 呈現的工作,都是由 Presenter 來做,而 View 本身只是 Presenter 所要使用的舞台而已,所以 View 原則上會相依於 Presenter,但是為了要做到關注點分離 (SoC 原則),所以在 View 和 Presenter 間都會加入一個介面 (ex: IView),然後以 IoC 的方式將 View 注射到 Presenter 中,而 Presenter 就使用介面所定義的方法去操控,而 View 就透過介面所定義的方法去呈現介面即可。但也因為受限於介面,所以 Presenter 只能依介面定義的動作去回應與處理,而不能再做更多的延伸功能,除非更改 View 的介面。
由上面各個架構的討論,我們可以得到以下的結果:
最後我想提的是,MVC 的包容度比 MVVM 和 MVP 要來的高,在 MVC 的 V 層,可以再進一步的包含 MVVM 或 MVP 的實作,而 C 層也可以使用 MVP (V 是輸出的資料) 來進一步切割資料的流動與輸出,M 層則可以類似 MVVM 的架構,當 V (元件) 有資料的異動時,VM 即可自動偵測到並更新 Model (資料庫)。當然,要用什麼樣的架構去設計,端看當時的系統環境與需求來決定,而不是只想著要用同一種架構去做所有的系統。
最近 MVC (Model-View-Controller) 和 MVVM (Model-View-ViewModel) 在微軟圈成為顯學,ASP.NET MVC 和 WPF 的 Prism (MVVM Framework) 功不可沒,MVC 和 MVVM 在概念上都是基於分層的,將呈現 (presentation) 與資料 (data) 分開的設計架構,M 和 V 基本上不是問題,但將這兩個整合的中間這層可就有很多的學問,另外,除了 MVC 和 MVVM 外,還有一個叫做 MVP (Model-View-Presenter) 的架構,這三個的設計概念非常類似,很容易會讓人傻傻分不清楚 ...
我們先來看各個架構的設計原則好了。
首先是 MVC,顧名思義,MVC 是將 Model, View 和 Controller 分離,讓彼此的職責 (responsibility) 能夠明確的分開,這樣不論是改 M, V 還是 C,都可以確保另外兩層可不用做任何修改,同時這樣的分層也可以加強程式的可測試性 (testability),View 和 Model 基本上是相關的,但它們並不會有直接的相依關係,而是由 Controller 去決定 Model 產生的資料,然後丟給 View 去做呈現,也就是說,Controller 是 Model 和 View 之間的協調者 (coordinator),View 和 Model 不能直接溝通,以確保責任的分離。而 Controller 可以只是一個繫結 Model 和 View 的小類別,也可以是大到包含 Workflow, Enterprise Services 或是做為外部系統的 Proxy Services 等的邏輯系統,MVC 各元件是可以分離的組件,也可以是分離的系統 (當然要設計一些機制在相互溝通)。
再來是 MVVM,MVVM 的架構一樣是 M, V 分離,但中間是以 VM (ViewModel) 來串接,這個 ViewModel 比較像是 View 的一個代理程式,它負責直接對 Model 做溝通,而 View 可以透過一些機制 (ex: Events, Two-way Databindings, ...) 來和 ViewModel 溝通以取得資料或將資料拋給 Model 做存取等工作,ViewModel 也可以作為和外部系統的代理程式,例如 Web Service 或是 REST Service 或是 Enterprise Services 等等,不過它和 MVC 不同的地方,就是 ViewModel 和 View 的黏合度比較高,因為 View 必須要透過 ViewModel 才可以取得 Model,而 ViewModel 又必須要處理來自 View 的通知訊息,所以雖然職責一樣分明,但是卻不像 MVC 那樣可以擴展到整個系統元件都能用。如果 MVVM 要和 MVP 比較的話,MVVM 會比 MVP 更靈活一點。
接著是 MVP,MVP 一樣也是職責分明,且 Model 與 View 分離的架構,但是這個 P (Presenter) 和 ViewModel 就很類似,不過就如同 Presenter (主持人) 這個字所代表的意義,所有主控 View 呈現的工作,都是由 Presenter 來做,而 View 本身只是 Presenter 所要使用的舞台而已,所以 View 原則上會相依於 Presenter,但是為了要做到關注點分離 (SoC 原則),所以在 View 和 Presenter 間都會加入一個介面 (ex: IView),然後以 IoC 的方式將 View 注射到 Presenter 中,而 Presenter 就使用介面所定義的方法去操控,而 View 就透過介面所定義的方法去呈現介面即可。但也因為受限於介面,所以 Presenter 只能依介面定義的動作去回應與處理,而不能再做更多的延伸功能,除非更改 View 的介面。
由上面各個架構的討論,我們可以得到以下的結果:
- MVC 架構適合於大型系統,它可以分層且可以在實體層面切割為不同的機器或服務,只要彼此間具有適當的通訊協定即可。
- MVVM 架構適合像 XAML 這種與程式碼無關 (code ignorance) 的使用者介面設計,只要 View 中下特定的指令與 ViewModel 串接,就可以享有 ViewModel 溝通的功能,而 ViewModel 只需做一些特別的介面實作,即可平順的和 View 溝通。
- MVP 架構適合集中由程式碼決定 View 動作的應用程式,而 View 只需要實作特定的介面即可,不需要太複雜的工作,但 Presenter 則可能會受限於 View 介面的動作,而無法做更進一步對 View 的控制。
最後我想提的是,MVC 的包容度比 MVVM 和 MVP 要來的高,在 MVC 的 V 層,可以再進一步的包含 MVVM 或 MVP 的實作,而 C 層也可以使用 MVP (V 是輸出的資料) 來進一步切割資料的流動與輸出,M 層則可以類似 MVVM 的架構,當 V (元件) 有資料的異動時,VM 即可自動偵測到並更新 Model (資料庫)。當然,要用什麼樣的架構去設計,端看當時的系統環境與需求來決定,而不是只想著要用同一種架構去做所有的系統。
Xcode 使用 SPM 安裝第三方套件
使用 SPM 安裝第三方套件 — Xcode 11 新功能
https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E5%95%8F%E9%A1%8C%E8%A7%A3%E7%AD%94%E9%9B%86/%E4%BD%BF%E7%94%A8-spm-%E5%AE%89%E8%A3%9D%E7%AC%AC%E4%B8%89%E6%96%B9%E5%A5%97%E4%BB%B6-xcode-11-%E6%96%B0%E5%8A%9F%E8%83%BD-2c4ffcf85b4b
開發 iOS App 時,我們有許多管理安裝第三方套件的方法,其中最為人熟知的三大套件管理天王為 CocoaPods,SPM(Swift Package Manager) & Carthage。
原本 CocoaPods 應該是其中最多人採用的,不過在 Xcode 11,一下子風雲變色,排名即將大搬風了。因為現在 Xcode 11 內建支援 SPM !
https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E5%95%8F%E9%A1%8C%E8%A7%A3%E7%AD%94%E9%9B%86/%E4%BD%BF%E7%94%A8-spm-%E5%AE%89%E8%A3%9D%E7%AC%AC%E4%B8%89%E6%96%B9%E5%A5%97%E4%BB%B6-xcode-11-%E6%96%B0%E5%8A%9F%E8%83%BD-2c4ffcf85b4b
開發 iOS App 時,我們有許多管理安裝第三方套件的方法,其中最為人熟知的三大套件管理天王為 CocoaPods,SPM(Swift Package Manager) & Carthage。
原本 CocoaPods 應該是其中最多人採用的,不過在 Xcode 11,一下子風雲變色,排名即將大搬風了。因為現在 Xcode 11 內建支援 SPM !
手機 APP 持久化儲存的方案整理
https://www.youtube.com/watch?v=ICSmvT1Wk8A&list=PLzKtnppOmiXAlARyp-aRjP0e-RsWiS4UW&index=48
iOS 資料儲存的方法
https://codertw.com/ios/326714/
https://www.itread01.com/p/383654.html
https://www.itread01.com/p/366949.htm
用來儲存應用程式設定和屬性、使用者儲存的資料,使用者再次開啟程式或開機後這些資料仍然存在。
plist 檔案能儲存字典和陣列,不能儲存物件。
資料歸檔可以儲存一些複雜的物件,資料儲存前會經過二進位制處理。
採用歸檔的形式來儲存資料,該資料物件需要遵守 NSCoding 協議,並且該物件對應的類必須提供 encodeWithCoder 和 initWithCoder 方法。前一個方法告訴系統怎麼對物件進行編碼,而後一個方法則是告訴系統怎麼對物件進行解碼。
以歸檔的形式儲存資料,只能一次性歸檔儲存以及一次性解壓,所以只能用於少量資料,即便只想改動資料的某一部分,就需要解壓整個資料,再歸檔整個資料。
coreData為了提高效率,需要將資料儲存在不同的資料庫中,比如在使用的時候,最好是將本地的資料儲存到記憶體中,這樣的目的是訪問速度比較快。
蘋果內建框架,和 Xcode 深度結合,可以很方便進行 ORM;但其上手學習成本較高,不容易掌握。穩定性也堪憂,很容易 crash;多線程的支持也比較雞肋。
直接使用 SQLite 資料庫的缺點包括了它沒有提供資料庫的建立方式;它的底層是基於 C 語言框架設計的,沒有面向物件的 API,用起來非常麻煩;複雜的資料模型的資料建表,非常麻煩。
在實際開發中,往往都是使用第三方開源、基於 SQLite 封裝的面向物件的框架。
Preference (偏好設定) 可以視為是一種 iOS 已經封裝好,方便開發者使用的 key-value 小型資料庫,少量資料時使用 Preference (偏好設定) 的效能會優於 SQL 資料庫,反之,大量資料就應該使用 SQL 資料庫。
Preference 會由 iOS 自動轉換為 Plist 進行持久化儲存,所以 Preference 與 Plist 兩者之間沒有效能差異的問題。
但是 Preference (偏好設定) 是自動存放於 Library/Preference,會被 iTunes 自動備份的,所以不可以拿來存放那些不應該被 iTunes 同步的資料,如果濫用會導致無法上架。
Plist 檔案 和 archiving (封存) 都是一次讀取整個檔案到記憶體中,所以如果需要持久化儲存的資料龐大到一定程度時,則應該使用 SQL 資料庫。
Q. Plist 檔案提取 UserDefaults 時會拉回整個 Array 再尋找相關 key 值,那麼 分開儲存 或 合併儲存在同一個 Array,那種方式效率較高?
網友實測結果是合併儲存在同一個 Array 較高。
=> 不過,原本就不應該使用 Plist 檔案儲存龐大資料的。分開存的優點是不用一次讀取所有資料到記憶體,所以應該仍是端視實際場景的需求做規劃。
plist vs sqlite 性能問題:
PList 是一種文件格式,用於存儲少量結構數據(小於數百KB),通常是字典。儘管可以輕鬆編寫代碼對 PList 進行排序,但 PList 本身並不具有排序功能。
SQLite 是一個完善的數據庫。文件大小(在 iPhone 上)基本上是無限的。內置排序功能。可以進行查詢和關係表設計。性能應與您可能想到的任何排序算法一樣好。
另一方面,sqlite 數據庫將只加載你請求的數據。我不確定您的數據是如何構建的,但您可以很容易地使用單個數據庫表創建鍵值對。 (一鍵列和值列的一個表)。然後,也可以寫一個 Objective-C 類來包裝數據庫查詢,以便能夠寫簡單的語句,如:
NSString *welcomeText = [[MyData sharedData] dataWithKey:@"WelcomeText"];
獲取將數據放入數據庫中並不一定非常困難,可以使用命令行 sqlite3 實用程序來批量加載數據。有一個名爲 .import 的命令將從文本文件中導入數據。
另外,有非常多理由不建議使用 coreData 資料庫。
使用 Plist、xml 等「非 SQL 解決方案」和 SQL(無論是原始數據還是作為 Core Data 中的持久性選項之一)之間的區別在於,「非 SQL 解決方案」會將整個持久化文檔加載到記憶體中,而 SQL 僅會加載當前所需的內容。
如果是少量的資料,由於 Plist 等「非 SQL 解決方案」是一次性加載所有資料到記憶體,這時候非 SQL 解決方案的效能會比 SQL 好;反之,大量資料則是選擇 SQL 方案。
iOS 資料儲存的方法
https://codertw.com/ios/326714/
https://www.itread01.com/p/383654.html
https://www.itread01.com/p/366949.htm
Bundle:應用程式在手機中的安裝路徑。
sandbox:專門來儲存當前 APP 自己的資料的路徑。
沙盒機制:在 iOS 中每個 APP 都擁有自己的沙盒,APP 只能訪問對應沙盒中儲存的資料,iOS 是不允許跨越沙盒去訪問資料的,所有的資料都是儲存在該沙盒的三個子目錄下:
Document
Library (Library/Caches, Library/Preference)
temp
Document:一般在該目錄下儲存一些比較重要的資料,比如遊戲相關的資料,當連線 iTunes後會自動同步資料。
必須注意,如果將資料資源儲存到該目錄,上架可能會被拒絕 (解決方案是直接設定該資料夾不被 iTunes 備份),總之,不能儲存從網上下載的資料,否則不能上架。
Library:儲存應用設定或者狀態資訊等,在該目錄下還有兩個子目錄:Caches 和 Preference
Library/Caches 存放快取檔案,iTunes 不會備份,因此檔案不會因 APP 退出而刪除 (一般使用SDWebImage 的快取資源都是儲存到這兒)
Library/Preference 儲存應用的所有偏好設定,iOS 的 Setting (設定) 會在該目錄查詢該應用的設定資訊,iTunes會同步資料。
temp:臨時檔案,iTunes不會備份該資料夾中的資料,這個資料夾中的資料,會因為應用的關閉而刪除。
sandbox:專門來儲存當前 APP 自己的資料的路徑。
沙盒機制:在 iOS 中每個 APP 都擁有自己的沙盒,APP 只能訪問對應沙盒中儲存的資料,iOS 是不允許跨越沙盒去訪問資料的,所有的資料都是儲存在該沙盒的三個子目錄下:
Document
Library (Library/Caches, Library/Preference)
temp
Document:一般在該目錄下儲存一些比較重要的資料,比如遊戲相關的資料,當連線 iTunes後會自動同步資料。
必須注意,如果將資料資源儲存到該目錄,上架可能會被拒絕 (解決方案是直接設定該資料夾不被 iTunes 備份),總之,不能儲存從網上下載的資料,否則不能上架。
Library:儲存應用設定或者狀態資訊等,在該目錄下還有兩個子目錄:Caches 和 Preference
Library/Caches 存放快取檔案,iTunes 不會備份,因此檔案不會因 APP 退出而刪除 (一般使用SDWebImage 的快取資源都是儲存到這兒)
Library/Preference 儲存應用的所有偏好設定,iOS 的 Setting (設定) 會在該目錄查詢該應用的設定資訊,iTunes會同步資料。
temp:臨時檔案,iTunes不會備份該資料夾中的資料,這個資料夾中的資料,會因為應用的關閉而刪除。
============================================
- Preference (偏好設定)
用來儲存應用程式設定和屬性、使用者儲存的資料,使用者再次開啟程式或開機後這些資料仍然存在。
NSUserDefaults 可以儲存的資料型別包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要儲存其他型別,則需要轉換為前面的型別,才能用NSUserDefaults儲存。
- Plist (屬性列表) 檔案
plist 檔案能儲存字典和陣列,不能儲存物件。
- 資料歸檔/解檔 (序列化/反序列化) (NSKeyedArchiver)
(無論是何種儲存方式,安全性最終都取決於資料是否加密後再持久化,而加密方式又有多種方案,比如說對稱金鑰、非對稱金鑰等等)
資料歸檔可以儲存一些複雜的物件,資料儲存前會經過二進位制處理。
採用歸檔的形式來儲存資料,該資料物件需要遵守 NSCoding 協議,並且該物件對應的類必須提供 encodeWithCoder 和 initWithCoder 方法。前一個方法告訴系統怎麼對物件進行編碼,而後一個方法則是告訴系統怎麼對物件進行解碼。
以歸檔的形式儲存資料,只能一次性歸檔儲存以及一次性解壓,所以只能用於少量資料,即便只想改動資料的某一部分,就需要解壓整個資料,再歸檔整個資料。
- coreData
coreData為了提高效率,需要將資料儲存在不同的資料庫中,比如在使用的時候,最好是將本地的資料儲存到記憶體中,這樣的目的是訪問速度比較快。
蘋果內建框架,和 Xcode 深度結合,可以很方便進行 ORM;但其上手學習成本較高,不容易掌握。穩定性也堪憂,很容易 crash;多線程的支持也比較雞肋。
- SQLite
直接使用 SQLite 資料庫的缺點包括了它沒有提供資料庫的建立方式;它的底層是基於 C 語言框架設計的,沒有面向物件的 API,用起來非常麻煩;複雜的資料模型的資料建表,非常麻煩。
在實際開發中,往往都是使用第三方開源、基於 SQLite 封裝的面向物件的框架。
在 iOS 裡操作 SQLite:
https://dotblogs.com.tw/toysboy21/2014/04/21/144813
Android 資料儲存的方法
https://codertw.com/android-%E9%96%8B%E7%99%BC/335701/
儲存少量的資料,且這些資料的格式非常簡單:字串型、基本型別的值。比如應用程式的各種配置資訊,是否開啟音效、是否使用震動效果、小遊戲的玩家積分等
可以在裝置本身的儲存裝置或者外接的儲存裝置中建立用於儲存資料的檔案。
在預設的狀態下,檔案不能在不同的程式間共享。
例如音訊,視訊,圖片和通訊錄,一般都採用此種方式進行儲存。
每個 ContentProvider 都會對外提供一個公共的 URI(包裝成 Uri 物件),如果應用程式有資料需要共享時,就需要使用 ContentProvider 為這些資料定義一個 URI,然後其他的應用程式就通過 Content Provider 傳入這個 URI 來對資料進行操作。
SQLite 是遵守 ACID 的關聯式資料庫管理系統,它包含在一個相對小的 C 程式庫中。與許多其它資料庫管理系統不同,SQLite 不是一個客戶端/伺服器結構的資料庫引擎,而是被整合在用戶程式中。
SQLite 遵守 ACID,實現了大多數 SQL 標準。作為嵌入式資料庫,是應用程式,如網頁瀏覽器,在本地/客戶端儲存資料的常見選擇。
它可能是最廣泛部署的資料庫引擎,因為它正在被一些流行的瀏覽器、作業系統、嵌入式系統所使用。同時,它有許多程式設計語言的語言繫結。
直接使用 SQLite 資料庫的缺點包括了它沒有提供資料庫的建立方式;它的底層是基於 C 語言框架設計的,沒有面向物件的 API,用起來非常麻煩;複雜的資料模型的資料建表,非常麻煩。
在實際開發中,往往都是使用第三方開源、基於 SQLite 封裝的面向物件的框架。
Wiki SQLite
https://en.wikipedia.org/wiki/SQLite
IOS DB 技術 框架比較
https://www.twblogs.net/a/5d7dcd1fbd9eee541c3449db
綜合來說,比較優先考慮的框架是 SQLite.swift 或 WCDB.swift
SQLite 的優點
SQLite 是輕量級的,沒有客戶端和服務器端之分,並且是跨平臺的關係型數據庫。
SQLite 是一個單文件,可以 copy 出來在其他地方用。
有一個 SQLite.swift 框架非常好用。
SQLite 的缺點
SQLite 在併發的讀寫方面性能不是很好,數據庫有時候可能會被某個讀寫操作獨佔,可能會導致其他的讀寫操作被阻塞或者出錯。
不支持 SQL92 標準,有時候語法不嚴格也可以通過,會養成不好習慣,導致不會維護。
需要寫很多 SQL 拼接語句,寫很多膠水代碼,容易通過 SQL 注入惡意代碼。
效率很低:SQL 基於字符串,命令行愛好者甚喜之。但對於基於現代 IDE 的移動開發者,卻是一大痛。字符串得不到任何編譯器的檢查,業務開發往往心中一團熱火,奮筆疾書下幾百行代碼,滿心歡喜點下 Run 後才發現:出錯了!靜心下來逐步看 log、斷點後才發現,噢,SELECT 敲成 SLEECT 了。改正,再等待編譯完成,此時已過去十幾分鐘。
SQLite3
獨立程式用來查詢和管理 SQLite 資料庫檔案。SQLite 的使用者可以把這個程式當作如何寫 SQLite 應用程式的範例。
SQLite3 直接使用比較麻煩,如果使用 Swift 版本推薦使用 SQLite.swift,這是很好的框架,比使用 FMDB 簡單,代碼簡潔很多。SQLite.swift 對 SQLite 進行了全面的封裝,擁有全面的純swift 接口,即使你不會 SQL 語句也可以使用數據庫。作者採用了鏈式編程的寫法,讓數據庫的管理變得優雅,可讀性也很強。
SQLite.swift
https://github.com/stephencelis/SQLite.swift
https://www.itread01.com/p/386972.html
Realm
在各平臺封裝、優化的優勢,較受移動開發者青睞。對於iOS開發者,key-value 的實現直接易懂,可以像使用 NSDictionary 一樣使用 Realm。並且 ORM 徹底,省去了拼裝 Object 的過程。但其對代碼侵入性很強,Realm 要求類繼承 RLMObject 的基類。這對於單繼承的 Objective-C 意味着不能再繼承其他自定義的子類。同時,key-value 數據庫對較爲複雜的查詢場景也比較無力。
FMDB
眾多開發者長期的使用經驗後發現,有性能瓶頸,比如說某個用戶長期未登錄,在登錄時收到大量消息,由於 FMDB 不支持多線程的寫操作,會導致寫入很慢。
基於 SQLite 封裝,對於有 SQLite 和 Objective-C 基礎的開發者來說,簡單易懂,可以直接上手;而缺點也正是在此,FMDB 只是將 SQLite 的 C 接口封裝成了 Objective-C 接口,沒有做更多優化,即所謂的膠水代碼 (Glue Code)。使用過程需要用大量的代碼拼接 SQL、拼裝 Object,既不方便也難以防止 SQL 注入。
如何使用 FMDB: https://medium.com/@mikru168/c9a3dc148c3c
WCDB
貼一份評論
WCDB.swift 使用官方文檔:
https://github.com/Tencent/wcdb/wiki/Swift-%E5%A2%9E%E5%88%A0%E6%9F%A5%E6%94%B9
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/642941/
https://www.zhihu.com/question/60914681
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/608382/
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/608379/
https://www.twblogs.net/a/5c64f8f1bd9eee06ee22b624
Android 資料儲存的方法
https://codertw.com/android-%E9%96%8B%E7%99%BC/335701/
- SharePreference
儲存少量的資料,且這些資料的格式非常簡單:字串型、基本型別的值。比如應用程式的各種配置資訊,是否開啟音效、是否使用震動效果、小遊戲的玩家積分等
- 檔案儲存
可以在裝置本身的儲存裝置或者外接的儲存裝置中建立用於儲存資料的檔案。
在預設的狀態下,檔案不能在不同的程式間共享。
- SQLite
- Content Provider
例如音訊,視訊,圖片和通訊錄,一般都採用此種方式進行儲存。
每個 ContentProvider 都會對外提供一個公共的 URI(包裝成 Uri 物件),如果應用程式有資料需要共享時,就需要使用 ContentProvider 為這些資料定義一個 URI,然後其他的應用程式就通過 Content Provider 傳入這個 URI 來對資料進行操作。
SQLite 是遵守 ACID 的關聯式資料庫管理系統,它包含在一個相對小的 C 程式庫中。與許多其它資料庫管理系統不同,SQLite 不是一個客戶端/伺服器結構的資料庫引擎,而是被整合在用戶程式中。
SQLite 遵守 ACID,實現了大多數 SQL 標準。作為嵌入式資料庫,是應用程式,如網頁瀏覽器,在本地/客戶端儲存資料的常見選擇。
它可能是最廣泛部署的資料庫引擎,因為它正在被一些流行的瀏覽器、作業系統、嵌入式系統所使用。同時,它有許多程式設計語言的語言繫結。
直接使用 SQLite 資料庫的缺點包括了它沒有提供資料庫的建立方式;它的底層是基於 C 語言框架設計的,沒有面向物件的 API,用起來非常麻煩;複雜的資料模型的資料建表,非常麻煩。
在實際開發中,往往都是使用第三方開源、基於 SQLite 封裝的面向物件的框架。
Wiki SQLite
https://en.wikipedia.org/wiki/SQLite
IOS DB 技術 框架比較
https://www.twblogs.net/a/5d7dcd1fbd9eee541c3449db
綜合來說,比較優先考慮的框架是 SQLite.swift 或 WCDB.swift
SQLite 的優點
SQLite 是輕量級的,沒有客戶端和服務器端之分,並且是跨平臺的關係型數據庫。
SQLite 是一個單文件,可以 copy 出來在其他地方用。
有一個 SQLite.swift 框架非常好用。
SQLite 的缺點
SQLite 在併發的讀寫方面性能不是很好,數據庫有時候可能會被某個讀寫操作獨佔,可能會導致其他的讀寫操作被阻塞或者出錯。
不支持 SQL92 標準,有時候語法不嚴格也可以通過,會養成不好習慣,導致不會維護。
需要寫很多 SQL 拼接語句,寫很多膠水代碼,容易通過 SQL 注入惡意代碼。
效率很低:SQL 基於字符串,命令行愛好者甚喜之。但對於基於現代 IDE 的移動開發者,卻是一大痛。字符串得不到任何編譯器的檢查,業務開發往往心中一團熱火,奮筆疾書下幾百行代碼,滿心歡喜點下 Run 後才發現:出錯了!靜心下來逐步看 log、斷點後才發現,噢,SELECT 敲成 SLEECT 了。改正,再等待編譯完成,此時已過去十幾分鐘。
SQLite3
獨立程式用來查詢和管理 SQLite 資料庫檔案。SQLite 的使用者可以把這個程式當作如何寫 SQLite 應用程式的範例。
SQLite3 直接使用比較麻煩,如果使用 Swift 版本推薦使用 SQLite.swift,這是很好的框架,比使用 FMDB 簡單,代碼簡潔很多。SQLite.swift 對 SQLite 進行了全面的封裝,擁有全面的純swift 接口,即使你不會 SQL 語句也可以使用數據庫。作者採用了鏈式編程的寫法,讓數據庫的管理變得優雅,可讀性也很強。
SQLite.swift
https://github.com/stephencelis/SQLite.swift
https://www.itread01.com/p/386972.html
Realm
在各平臺封裝、優化的優勢,較受移動開發者青睞。對於iOS開發者,key-value 的實現直接易懂,可以像使用 NSDictionary 一樣使用 Realm。並且 ORM 徹底,省去了拼裝 Object 的過程。但其對代碼侵入性很強,Realm 要求類繼承 RLMObject 的基類。這對於單繼承的 Objective-C 意味着不能再繼承其他自定義的子類。同時,key-value 數據庫對較爲複雜的查詢場景也比較無力。
FMDB
眾多開發者長期的使用經驗後發現,有性能瓶頸,比如說某個用戶長期未登錄,在登錄時收到大量消息,由於 FMDB 不支持多線程的寫操作,會導致寫入很慢。
基於 SQLite 封裝,對於有 SQLite 和 Objective-C 基礎的開發者來說,簡單易懂,可以直接上手;而缺點也正是在此,FMDB 只是將 SQLite 的 C 接口封裝成了 Objective-C 接口,沒有做更多優化,即所謂的膠水代碼 (Glue Code)。使用過程需要用大量的代碼拼接 SQL、拼裝 Object,既不方便也難以防止 SQL 注入。
如何使用 FMDB: https://medium.com/@mikru168/c9a3dc148c3c
WCDB
貼一份評論
WCDB.swift 使用官方文檔:
https://github.com/Tencent/wcdb/wiki/Swift-%E5%A2%9E%E5%88%A0%E6%9F%A5%E6%94%B9
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/642941/
https://www.zhihu.com/question/60914681
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/608382/
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/608379/
https://www.twblogs.net/a/5c64f8f1bd9eee06ee22b624
獲取 iOS 設備的唯一識別 Device ID
https://cg2010studio.com/2016/05/31/idfa%E3%80%81idfv%E3%80%81uuid/
https://medium.com/appworks-school/device-check-35556ab74d
https://www.jianshu.com/p/9e885c3e6b0a
https://blog.csdn.net/zhtl3333/article/details/51094381
https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor
每次送審 App,最後 itunes connect 都會問,有沒有使用 IDFA,若沒有正確回答,那麼這個版本就會被拒絕!
想要追蹤、統計、分析用戶,自然離不開用戶唯一識別碼,這是每個公司都會面臨的問題。在歷史上唯一識別碼很多,如 UDID、MAC位址、OpenUDID 等,現在好用的只剩下 IDFA、IDFV、UUID + keyChain。
一開始,Apple 允許開發者取得用戶 Device 的 UDID(Unique Device Identifier),以達成裝置綁定或是追蹤。這個值是唯一且永遠不會變的。
但這其實存在隱私問題,UDID 等同 Device 的身分證字號,如果開發者可以隨意取得 UDID ,代表他們可以透過各種分析來取得『多於開發者應取得的資訊』。
所以這個方法後來被 Apple 禁用了。
其後 Apple 提供了另一種識別方式 — IDFV (Identifier For Vendor)
如果說 UDID 是 Device 的身分證字號, IDFV 比較像是 Device 的『工號』
每個 App 開發商能取到的 Device IDFV 都不一樣。
舉例來說,User 下載了 A 開發商的 a, b 兩款 App,同時下載了 B 開發商的 c App,
A 開發商如果用上面的程式碼取得 IDFV, 在兩款 app 中皆會取到 1234,
而 B 開發商會取到 5678。
而這個 IDFV 既然是 “identifier For Vendor” (IDFV) ,就算刪除 App ,重新下載過後仍然會取到一樣的 IDFV 。
不過,如果將手機內同一個開發商的 App 全數刪除後,這個 IDFV 會被重置,也就是說下次 User 再下載同一個開發商的 App,會拿到不同的 IDFV。
而由於如果用戶卸載又重新安裝同一個 App,其 IDFV 可能會改變,這樣子將無法實現某些促銷活動,比如說 30 天試用,
因此,這時候需要搭配使用另外一個方法:Device Check
舉個例子,今天一個 App 提供了 30 天的免費試用,期限到了之後透過 Device Check 的 API 把裝置從狀態 A(試用中)標註為狀態 B(已過期),之後不論是刪除 App 重新下載,或是系統重置,都不會影響到這個狀態的判定。而這個狀態,其實就是兩個 bit 所組成的,最多四種狀態而已。
接著來看一下 Device Check API 的運作流程:
IDFA(Advertising Identifier):可以理解為廣告 id,Apple 提供的用於追蹤用戶的廣告識別碼。
在同一個設備上的所有 App 都會取到相同的值,是蘋果專門給各廣告提供商用來追踪用戶而設的,用戶可以在設置 => 隱私 => 廣告追踪裡重置此 id 的值,或限制此 id 的使用,故此 id 有可能會取不到值,但好在 Apple 默認是允許追踪的,而且一般用戶都不知道有這個設置,所以基本上已經足以用來監測廣告效果。
由於 IDFA 可能會出現取不到的情況,所以不可以用來識別用戶。
訂閱:
文章 (Atom)
程式語言編年史
程式語言編年史原文 下面這張圖片描繪了整個程式語言的歷史。包括各種程式語言的發明人、程式語言的特點和適用領域、被什麼網站或公司使用等 (檢視 完整高清圖 )。 之所以會有那麼多不同的程式語言是因為設計程式語言的初衷不同、對語言學習曲線的追求不同、不同程式之間的執行成本差異...

















