IOS 学习笔记(NSCoding , QR Code)PART 11
昨天有几件好事发生:
- 今天终于收到了顾爷的书,果然和预期的一样好。
- 今天在大望路地铁帮助了一位白种人,虽然没有明确地指明地址,但是也告诉了他正确的方向,I know he was gonna fuck a Chinese girl,but that was not my business。
- 作文又得了一次95分。
- 牙不疼了。
知识的持续摄取让我开始觉得内心强大才是真的强大。继续写笔记:
Storage Custom Object With NSCoding
之前提到的NSArray的writeToFile方法,在存放标准的Objective数据结构时没有问题,可以存放NSNumer,NSString,NSDictionary,但是自定义的对象就存放不能了,有两种方案解决这个问题。
- 将所有数据都以原生的数据结构存储,然后还是分别调用NSArray和NSDictionary的writeToFile方法。
- 让自定义对象实现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机型上运行正常)。