PAPreferences 0.5

PAPreferences 0.5

测试测试
Lang语言 Obj-CObjective C
许可证 BSD
发布最后一次发布2015年8月

Denis HennessyDenis Hennessy维护。



  • 作者:
  • Denis Hennessy

使用NSUserDefaults存储用户偏好的简单方法。

PAPreferences将动态属性映射到NSUserDefaults的getter和setter,这样您就可以像访问对象上的常规属性一样访问默认值。这个对象通常是单例的,因为您通常希望整个应用程序只有一套偏好设置。

支持iOS和OSX。

将PAPreferences添加到您的项目中

将PAPreferences添加到您的项目的最简单方法是使用CocoaPods。将以下行添加到您的Podfile中

    pod 'PAPreferences'

如果您更喜欢手动集成,只需将代码“PAPreferences/*.{m,h}”复制到您的项目中。

创建偏好设置单例

首先,创建一个包含您设置属性的PAPreferences子类(注意,所有属性都应该有assign存储说明符)

#import "PAPreferences.h"

@interface MyPreferences : PAPreferences
@property (nonatomic, assign) NSString *theme;
@property (nonatomic, assign) NSArray *favorites;
@property (nonatomic, assign) BOOL hasSeenIntro;
@end

在实现文件中,将每个属性标记为动态

#import "MyPreferences.h"

@implementation MyPreferences
@dynamic theme;
@dynamic favorites;
@dynamic hasSeenIntro;
@end

访问偏好设置

可以使用sharedInstance类方法来访问单例

    if (![MyPreferences sharedInstance].hasSeenIntro) {
        // ...
        [MyPreferences sharedInstance].hasSeenIntro = YES;
    }

支持的属性类型

PAPreferences支持以下属性类型

  • NSInteger
  • NSString
  • NSArray
  • NSDictionary
  • NSURL
  • NSData
  • NSDate
  • NSNumber
  • BOOL
  • float
  • double
  • 符合NSCoding协议的类(包括NSSecureCoding)。

虽然您可以设置可变值的属性,但您将目前只能得到不可变副本。类似于使用NSUserDefaults直接。

在偏好设置更改时更新UI

每当对某个属性进行更改时,都会发布一个PAPreferencesDidChangeNotification通知(其对象设置为PAPreferences子类)。

它是如何工作的

当首次访问一个属性时,该选择器会映射到与NSUserDefaults类交互的方法。例如,这行

    hasSeenIntro = YES;

扩展为对以下类似方法进行调用

- (void)setHasSeenIntro:(BOOL)value {
    [[NSUserDefaults standardUserDefaults] setBool:value forKey:@"hasSeenIntro"];
    [[NSNotificationCenter defaultCenter] postNotificationName:PAPreferencesDidChangeNotification object:self];
}

设置默认值

我更喜欢在代码中设置默认值,而不是使用传统的NSUserDefaults方法。这也是一个非常有用的机制,用于设置您的应用安装的第一个和最后一个版本。有了这些值,您可以轻松地将现有用户迁移到新偏好设置。以下是我的Focus Time应用的一个示例

- (id)init {
    if (self = [super init]) {
        NSString *version = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];
        if (self.firstVersionInstalled == nil) {
            self.firstVersionInstalled = version;

            // Set defaults for new users
            self.pomodoroLength = 1500;
            self.workStartSound = @"alert_gentle_jingle";
            self.workEndSound = @"alert_ring";
            // . . .
        }

        self.lastVersionInstalled = version;
    }
    return self;
}

与iOS扩展一起工作

要共享iOS中主机应用程序和扩展之间的设置,您必须使用 initWithSuiteName: 创建的NSUserDefaults实例,而不是 standardUserDefaults。为了支持这一点,PAPreferences的子类可以提供一个覆盖默认值的 userDefaults 实现。这也是缓存实例的好方法。以下是一个示例实现

- (NSUserDefaults *)userDefaults {
    static NSUserDefaults *_cachedDefaults;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _cachedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.peerassembly.myapp"];
    });

    return _cachedDefaults;
}

示例

如何使用库的最佳示例在单元测试中 - PAPreferencesTests.m。然而,在iOS示例中还包括一个简单的偏好设置文件。

故障排除

如果您定义了一个属性但后来忘记了将其实现文件中的 @dynamic 行添加到其中,那么一切似乎都在正常工作,但实际上编译器正在为该属性创建一个内存中的存储(就像您使用了 @synthesize 行一样。这些属性不会保存到NSUserDefaults中。为了防止这种情况,归类于类的声明是一个好习惯

#pragma clang diagnostic push
#pragma clang diagnostic error "-Wobjc-missing-property-synthesis"

#pragma clang diagnostic pop

变更日志

0.4

  • 添加指定NSUserDefaults实例的能力,而不是标准的。如果您在与iOS上的扩展共享设置,这一点很重要
  • 修复iOS示例,以便单元测试可以在iOS和OSX上运行(以前,由于在测试运行之前,初始视图控制器访问了单例,这些测试在iOS上失败了)。

0.3

  • 添加每次更新属性时自动调用同步的功能(以及一个用于关闭它的标志)
  • 添加对NSDate和NSCoding的支持
  • 重构getter & setter辅助函数

感谢 @Janx2 和 @creatd 提交的拉取请求。

0.2

  • 删除对不受支持类型的无效警告

0.1

  • 初始发布

联系

要了解有关此库以及其他库的更新,请在Twitter(@denishennessy)或App.net(@denishennessy)上关注我。

如果您遇到错误,或者想到了一个出色的全新功能,那么在GitHub上打开一个问题可能是分享它的最佳方式。实际上,最好的方法是给我发送一个拉取请求...

对于其他任何问题,电子邮件始终有效:[email protected]

许可

Copyright (c) 2014, Denis Hennessy (Peer Assembly - http://peerassembly.com)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of Peer Assembly, Denis Hennessy nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL PEER ASSEMBLY OR DENIS HENNESSY BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.