ios開發--應用設置及用戶預設設置【2、讀取應用中的設置】

来源:http://www.cnblogs.com/azuo/archive/2016/01/04/5098544.html
-Advertisement-
Play Games

在上一節中,我們通過探討應用的系統設置的基本功能,瞭解運用bundle捆綁包以及plist文件的基本開發。用戶能夠使用設置應用來聲明他們的偏好設置,那麼我們怎樣去調用用戶所設置的參數呢,上節我們只創建了Setting.bundle捆綁包,在這個基礎上,這一節,我們將繼續討論,關於如何讀取應用中...


        在上一節中,我們通過探討應用的系統設置的基本功能,瞭解運用bundle捆綁包以及plist文件的基本開發。用戶能夠使用設置應用來聲明他們的偏好設置,那麼我們怎樣去調用用戶所設置的參數呢,上節我們只創建了Setting.bundle捆綁包,在這個基礎上,這一節,我們將繼續討論,關於如何讀取應用中的設置,以及讓app應用與設置的數據同步。

我們將通過本節內容達到的效果如下:

    

【圖1 app應用界面】

【本次開發環境: Xcode:7.2     iOS Simulator:iphone6S plus   By:啊左】    

 

一、獲取用戶設置

1、NSUserDefaults類的介紹

訪問用戶的設置需要調用NSUserDefaults類,NSUserDefaults為單例類,需要調用類方法standardUserDefaults來獲取指向標準用戶預設設置的指針:

NSUserDefaults *defaults =  [NSUserDefaults standardUserDefaults];
defaults可以像NSDictionary類一樣進方法的調用,例如“objectForKey:”,會返回一個Object-C對象,如NSString、NSDate、NSNumber。若需要獲取整型、浮點型等方式,可以用“intForKey:”、“floatForKey”、“boolForKey”等其他方法。

2、鍵值

在上一節中,plist屬性列表中的偏好設置欄位,每個條目都有特定的鍵,例如Item1對應的是“officer”、滑塊Item6對應的是“SliderValue”,這些鍵都是做為調用該項的ID。

因此我們可以先把這些鍵放在自己創建的頭文件"settingHead.h"中,便於調用。內容如下:

#ifndef settingHead_h
#define settingHead_h

#define Officer            @"officer"
#define AuthorizationCode  @"authorizationCode"
#define Rank               @"rank"
#define IsWarp             @"IsWarp"
#define SliderValue        @"SliderValue"
#define moreFactor         @"MoresliderValue"

#endif /* settingHead_h */

3、關聯相關控制項

接下來,我們使用Main.storyboard創建14個label、一個開關、一個滑塊,為左邊8個label修改為Officer、code等內容如下:


【圖2  Main.storyboard設置界面】

確認該視圖關聯的是ViewController,然後打開輔助編輯器(或者在Main.storyboard界面按下option+command+return),按住control鍵分別從Main.storyboard圖標拖動到ViewController.h中,為右邊6個label以及滑塊、開關添加在ViewController.h的介面,代碼如下

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//5個label介面
@property (weak, nonatomic) IBOutlet UILabel *label1;
@property (weak, nonatomic) IBOutlet UILabel *label2;
@property (weak, nonatomic) IBOutlet UILabel *label3;
@property (weak, nonatomic) IBOutlet UILabel *label4;
@property (weak, nonatomic) IBOutlet UILabel *label5;

//滑塊、開關介面
@property (weak, nonatomic) IBOutlet UISwitch *enginesSwitch;
@property (weak, nonatomic) IBOutlet UISlider *WarpSlider;

//滑塊、開關的介面方法(修改用戶預設設置)
- (IBAction)enginesSwitchBtn:(UISwitch *)sender;
- (IBAction)WarpSliderBtn:(UISlider *)sender;

@end

在ViewController.m中,敲入: #import "settingHead.h"   添加鍵集合的頭文件,然後添加一個更新app界面數據的方法:  -(void)refreshValue ,代碼如下:

 1 #import "ViewController.h"
 2 #import "settingHead.h"
 3 
 4 @implementation ViewController
 5 
 6 - (void)viewDidLoad {
 7     [super viewDidLoad];
 8     self.view.backgroundColor = [UIColor orangeColor];
 9     [self refreshValue];
10 }
11 
12 -(void)refreshValue
13 {
14     NSUserDefaults *defaults =  [NSUserDefaults standardUserDefaults];
15     self.label1.text = [defaults objectForKey:Officer];
16     self.label2.text = [defaults objectForKey:AuthorizationCode];
17     self.label3.text = [defaults objectForKey:Rank];
18     self.label4.text = [defaults boolForKey:IsWarp]?@"Enable":@"Disable";
19     self.label5.text = [[defaults objectForKey:SliderValue] stringValue];
20     
21     self.enginesSwitch.on = [defaults boolForKey:IsWarp];
22     self.WarpSlider.value = [defaults floatForKey:SliderValue];
23 }

 

在以上的refreshValue方法,首先通過調用NSUserDefaults類獲取了標準用戶預設設置,然後調用objectForKey方法訪問獲取對應鍵值的內容、

需要註意的是label1到label5,除了label4外,都是以NSString對象的形式返回,label4中defaults調用鍵值為IsWarp的方法返回的是bool值。因此我們得到結果後給予判斷再賦值給label4的文本;

而label5由於是內容為滑塊的值,是以NSNumber形式返回的,因此需要調用改對象的stringValue方法來獲取它存儲的值的字元串表示。

 

二、在應用中修改用戶預設設置

應用中修改用戶預設設置所調用的方法為:“setObject forKey”,在在ViewController.m中,需要在關聯的開關滑塊方法WarpSliderBtn、enginesSwitchBtn中添加如下代碼:

 1 - (IBAction)WarpSliderBtn:(UISlider *)sender {
 2     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 3     [defaults setFloat:self.WarpSlider.value forKey:SliderValue];
 4     [defaults synchronize];
 5 }
 6 - (IBAction)enginesSwitchBtn:(UISwitch *)sender {
 7     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 8     [defaults setBool:self.enginesSwitch.on forKey:IsWarp];
 9     [defaults synchronize];
10 }

運行、我們可以看到如下界面:

【圖3  】

我們可以看到,即使我們為Multi Value、IsWarp設置預設值得,依然不會顯示在我們的應用中,這是因為:我們的應用完全不知道設置捆綁包中已保存的該應用的偏好設置,即使我們在設置中設置好相應的值,然後再運行一次可以看到應用上顯示值,但是當我們刪除掉運用再運行一次,還是顯示為空值,而不能看到預設值。

我們可以作如下處理:如果我們嘗試查找未設置的鍵/值,但該鍵至少會有一個預設值,可以用registerDefaults:方法,為了使得改設置在整個運用中都能有效,最好在應用啟動時就調用它

因此,點擊AppDelegate.m文件,添加"settingHead.h”頭文件,然後在didFinishLaunchingWithOptions中鍵入以下代碼:

1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
2     // Override point for customization after application launch.
3     
4     NSDictionary *dict = @{@"warp":@YES,
5                            @"warpFactor":@5,
6                            };
7     [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
8     return YES;
9 }

按下command+shift+H ,在ios模擬器主頁上面長按我們創建的app,刪除它,然後按下command+R再運行一次我們可以看到剛剛我們通過registerDefaults:方法設置的預設值。

 

三、同步系統設置與應用上的數據

現在我們可以嘗試下通過調整應用來修改系統設置的值,但是奇怪的是:當我們修改系統設置,再打開app應用上面的數據也沒有變化,當我們修改app上面的滑塊與開關,再查看系統設置也是沒有變化。

   這也是ios系統的一個特點:當應用在運行時返回主屏幕,並不會退出應用,而是由操作系統在後臺將其暫停了,這樣它就可以隨時能夠快速啟動,因為用戶在切換應用時,重新喚醒一個應用比從新啟動一個應用要省下很多時間,這使得ios系統下應用的切換更加高效快捷。這也是後臺應用的基本知識。

那麼在這個例子中,我們應該如何同步更新數據呢,其實只要在喚醒的時候添加一個功能:重新載入同步用戶偏好設置並重新顯示它們的內容。

接下來我們需要運用到“通知”這一個對象之間進行通信的輕量級機制。通知中心是一個單例對象,作用是在對象之間傳送通知。“通知”通常是在某些事件發生時發送的說明,UIApplicaton類會發送大量的通知(可以從Xcode的文檔閱讀器中找到這些更加詳細的內容,在UIApplicaton頁面的底部)。

應用在回到前臺時,刷新一下它顯示的內容,因此我們需要調用名為 “UIApplicationWillEnterForegroundNotification”的通知,編寫viewWillAppear:方法時,我們會訂閱該通知,並告訴通知中心該通知出現時需要調用的方法,這個方法我們可以命名為:“applicationwillenterforegound”、

點擊ViewController.m,添加以下代碼:

1 -(void)applicationwillenterforegound:(NSNotification *)notification
2 {
3     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
4     //進行應用設置與控制項上的數據同步
5     [defaults synchronize];
6     [self refreshValue];
7 }

其中,我們可以看到defaults調用synchronize方法,該方法強制用戶預設值保存尚未保存的修改,然後從存儲中重新載入所有未修改的偏好設置。事實上,這是在強制它重新讀取已保存的偏好設置,從而獲取設置應用中所作的修改,然後調用refreshValue:方法來個更新顯示的內容。

Now,我們需要在ViewController.m中實現viewWillAppear:方法,使得該控制器訂閱我們關註的“UIApplicationWillEnterForegroundNotification”通知。如下:

1 -(void)viewWillAppear:(BOOL)animated
2 {
3     [super viewWillAppear:animated];
4     //註冊觀測者
5     UIApplication *app = [UIApplication sharedApplication];
6     [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(applicationwillenterforegound:) name:UIApplicationWillEnterForegroundNotification object:app];
7 }

在該addObserver:  selectornameobject: 方法中,

observer傳遞的是self,也就是我們的控制器本身;

selector,調用的是我們自己寫的選擇器方法,用於告訴通知中心在該通知發出時調用該方法;

name是我們要接収的通知的名稱,一般可以在Xcode的文檔閱讀器中找到這些更加詳細的內容;

最後一個參數app,是我們關心的獲得通知的來源對象,如果改為nil,表示只要有方法發出“UIApplicationWillEnterForegroundNotification”通知,我們就會得到通知。

這樣,我們就完成了,回到app前臺重新載入內容的開發。

 

那麼當用戶在應用中操作控制項,又怎樣把內容同步到系統的預設設置裡面呢?很簡單,只要在我們設置的控制項,開關與滑塊的方法中添加一行 “[defaults synchronize]” 即可。

- (IBAction)WarpSliderBtn:(UISlider *)sender {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setFloat:self.WarpSlider.value forKey:SliderValue];
    [defaults synchronize];
}
- (IBAction)enginesSwitchBtn:(UISwitch *)sender {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:self.enginesSwitch.on forKey:IsWarp];
    [defaults synchronize];
}

【註意:調用synchronize:方法的開銷會很大,因為要比較應用以及系統設置中的所有用戶偏好設置,因此應該儘量減少對synchronize的調用,不過像我們此次的項目中,在響應每個用戶操作時調用它一次,並不會造成任何顯著的性能問題。

當然,為了使得系統的工作過程更加清晰,我們可以在通知系統不需要接收到通知時,在viewDidDisappear中撤銷註冊,因此我們可以添加代碼如下
1 -(void)viewDidDisappear:(BOOL)animated
2 {
3     [super viewDidDisappear:animated];
4     /*
5       註銷監聽  也可以用removeObserver:self name: object:方法來撤銷對特定通知的訂閱,但以下這種更加方便:直接告知確保通知中心徹底忘記我們的observer的方法,不管註冊它是為了        接收多少種通知。
6      */
7     [[NSNotificationCenter defaultCenter] removeObserver:self];
8 }

按下“command+R”運行。在應用的空間【參照圖1】以及系統設置上面編輯,以及切換時查看同步效果。

       做完以上工作,我們已經可以瞭解了設置應用和用戶預設機制的基本概念,懂得如何添加捆綁包,如何為應用的偏好設置構建結構化的視圖,通過NSUserDedeults讀寫偏好設置以及修改設置內容,並且開發了相關的項目。

 

By:啊左~~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原理:使用公用表表達式的遞歸查詢 傳送門:https://msdn.microsoft.com/zh-cn/library/ms186243 問題:指定一個父級,查詢出該父級下麵的所有節點。 舉例說明:存在表 ComponentI為子,PP_ComponentID為父。 CREATE PROCEDU...
  • 掃描與查找操作均是SQL Server從表或索引中讀取數據採用的迭代器,這些也是SQL Server支持的最基本的運算。幾乎在每一個查詢計劃中都可以找到,因此理解它們的不同是很重要的,掃描是在整張表上進行處理,而索引是在整個頁級上進行處理,而查找則返回特定謂詞上一個或多個範圍內的數據行。下麵讓我們....
  • 1、壓縮資料庫dbcc shrinkdatabase(dbname)2、轉移資料庫給新用戶已存在用戶許可權exec sp_change_users_login'update_one','newgame','oldname'go3、檢查備份集RESTORE VERIFYONLY from disk='E...
  • 又是想到什麼寫什麼系列……上次http://www.cnblogs.com/Gin-23333/p/5096638.html 寫了一下,今天補充點其它的1、在事務裡面的影響,臨時表可以被回滾 而表變數是不能回滾的。簡單的例子DECLARE @T AS TABLE(ID INT,Name NVARCH...
  • 不行,基本一重啟就不能再次訪問了,每次都要查問題,可以放棄Oracle麽,太垃圾了。1.操作系統版本用於安裝資料庫的操作系統鏡像文件名為:cn_windows_server_2012_r2_vl_with_update_x64_dvd_6052729.iso安裝DataCenter(帶GUI)版本虛...
  • 總結 View的z值由兩部分組成,elevation和translationZ. eleavation是靜態的成員,translationZ是用來做動畫。 Z = elevation + translationZ 在佈局中使用 android:elevation屬性去定義 在代碼中使用 View.s...
  • 看完過後,你會學到:1學習IOS開發中的分類實現,2以及類方法的書寫,3以及字元串的MD5加密/解密.---------------------------wolfhous------------------[1]新建工程,新建分類[2]分類的命名方式以及類的選擇[3]書寫NSString分類的類方...
  • 1、錯誤代碼:No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=armv7 armv7s)build 這個target的時候命令行報錯。可以在 build setting 中,...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...