IOS 学习笔记(NSCoding , QR Code)PART 11

昨天有几件好事发生:

  1. 今天终于收到了顾爷的书,果然和预期的一样好。
  2. 今天在大望路地铁帮助了一位白种人,虽然没有明确地指明地址,但是也告诉了他正确的方向,I know he was gonna fuck a Chinese girl,but that was not my business。
  3. 作文又得了一次95分。
  4. 牙不疼了。
    知识的持续摄取让我开始觉得内心强大才是真的强大。继续写笔记:

Storage Custom Object With NSCoding

之前提到的NSArray的writeToFile方法,在存放标准的Objective数据结构时没有问题,可以存放NSNumer,NSString,NSDictionary,但是自定义的对象就存放不能了,有两种方案解决这个问题。

  1. 将所有数据都以原生的数据结构存储,然后还是分别调用NSArray和NSDictionary的writeToFile方法。
  2. 让自定义对象实现NSCoding的Delegate,代码如下:
    #import <Foundation/Foundation.h>

@interface ExampleVO : NSObject <NSCoding>
@property(nonatomic,strong)NSString *eg;
@property(nonatomic,strong)NSString *translation;
@property(nonatomic,strong)NSString *audio;
@end

#import "ExampleVO.h"

@implementation ExampleVO

static NSString *TranslationArchiveKey = @"translation";
static NSString *AudioArchiveKey = @"audio";
static NSString *EGArchiveKey = @"eg";

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.translation forKey:TranslationArchiveKey];
    [coder encodeObject:self.audio forKey:AudioArchiveKey];
    [coder encodeObject:self.eg forKey:EGArchiveKey];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if (self != nil) {
        self.translation = [aDecoder decodeObjectForKey:TranslationArchiveKey];
        self.audio = [aDecoder decodeObjectForKey:AudioArchiveKey];
        self.eg = [aDecoder decodeObjectForKey:EGArchiveKey];
    }
    return self;
}
@end

存放操作:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *histroySearch = [documentsDirectory stringByAppendingPathComponent:@"histroySearch.dat"];
    NSData *achiveData = [NSKeyedArchiver archivedDataWithRootObject:self.histroySearch];
    [achiveData writeToFile:histroySearch atomically:YES];

提取操作:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *histroySearch = [documentsDirectory stringByAppendingPathComponent:@"histroySearch.dat"];
    self.histroySearch = [NSKeyedUnarchiver unarchiveObjectWithFile:histroySearch];

QRCode

QRCode如此流行,我也顺手整了一下,分别是用Javascript生成QRCode和在iOS端读取。Javascript的库在这里,qrcode.js,太容易了,我就不列代码了。

iOS端用的是ZBar,这名字稍微一不小心就容易说成脏话呢,不如干脆叫GeeBar算了,要不我立个Git项目叫这名。这里遇到了一些小问题,就是它的现存版本比较老了,好处是开源,支持多平台。这里有一篇详细的教程,我搬过来部分核心步骤,以备后用。

1. 从这里Down一个dmg包,然后把对应的ZBarSDK文件夹拽到你的XCode项目中。

2. 它依赖如下framework,请挨个在项目的Build Phases的Link Binary With Libraries 中添加。

  • AVFoundation.framework
  • CoreGraphics.framework
  • CoreMedia.framework
  • CoreAudio.framework
  • CoreVideo.framework
  • QuartzCore.framework
  • libiconv.dylib
    3. 在要使用的类中实现对应的Delegate,ZBarReaderDelegate.下面是代码部分
    - (IBAction)pickQRCode:(id)sender {
    ZBarReaderViewController *codeReader = [ZBarReaderViewController new];
    codeReader.readerDelegate = self;
    codeReader.supportedOrientationsMask = ZBarOrientationMaskAll;
    
    ZBarImageScanner *scanner = codeReader.scanner;
    [scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];
    
    [self presentViewController:codeReader animated:YES completion:nil];

}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;

NSLog(@“data from qrcode:%@”,symbol.data);
[self dismissViewControllerAnimated:YES completion:nil];

}
这些都做完之后,会发现在simulator–>iPhone retina(3.5-inch)上运行正常,simulator–>iPhone retina(4-inch 64-bit)上编译不能。原因是ZBar这个版本木有提供arm64支持。解决办法是,在Build Setting中移除Architectures对应的arm64支持的项目(尚未真机测试,无法确保在5s机型上运行正常)。