终于把iOS平台下的加密算法调通了,在这里记录一下,并说一下遇到的N种加密问题。
首先要说明一下我所遇到的需要加密的数据:向服务器端发送用户名与密码进行portal认证,当然为了显示出专业性(扯淡的说),服务器提供商要求发送经过四层加密后的数据,分别是:
1、用户名、密码分别用Base64加密
2、用户名,密码和发送时间相加之后进行DES加密
3、对加密后的结果再进行一次Base64加密
4、最后把结果用RLENCODE 转化成UTF-8
这其中主要使用到Base64加密与DES加密,再就是数据转换,过程如下:
//分别对用户及密码进行Base64加密
NSString *BASE64userName = [GTMBase64 base64Encode:[Puser.username dataUsingEncoding: NSUTF8StringEncoding]];
NSString *BASE64password = [GTMBase64 base64Encode:[Puser.password dataUsingEncoding: NSUTF8StringEncoding]];
//串联用户及密码字符串
NSString *allStr = [NSString stringWithFormat:@"username=%@,password=%@,timestamp=%@",BASE64userName,BASE64password,[Util getCurrentDateTime]];
Airsource_Log_Debug(@”allStr = %@”,allStr);
//DES加密
NSData *allStrData = [allStr dataUsingEncoding: NSUTF8StringEncoding];
NSData *DESData = [EncryptUtil DESEncrypt:allStrData WithKey:Post_SHAREKEY];
//Base64加密
NSString *Base64DESStr = [GTMBase64 base64Encode:DESData];
//Airsource_Log_Debug(@”Base64DESStr = %@”,Base64DESStr);
//URLENCODE 转化成UTF-8
NSString *URLENCODEBase64DESStr = [Base64DESStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//Airsource_Log_Debug(@”URLENCODEBase64DESStr = %@”,URLENCODEBase64DESStr);
//串联加密后的所有字符串
NSString *ipStr = [localIPAddress localIPAddress];//获取本地IP
Airsource_Log_Debug(@”ipStr = %@”,ipStr );
strurl = [NSString stringWithFormat:@"%@%@%@&userip=%@&userPublicIp=%@&language=Chinese",strurl,userInfo,URLENCODEBase64DESStr,ipStr,ipStr];
Airsource_Log_Debug(@”strurl = %@”,strurl );
终于得到了最后需要发送的加密string了。
其中用到的加密方法:GTMBase64
#import “GTMBase64.h”
static const char *kBase64EncodeChars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;
static const char *kWebSafeBase64EncodeChars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_”;
static const char kBase64PaddingChar = ‘=’;
static const char kBase64InvalidChar = 99;
@interface GTMBase64 (PrivateMethods)
+(NSData *)baseEncode:(const void *)bytes
length:(NSUInteger)length
charset:(const char *)charset
padded:(BOOL)padded;
@end
@implementation GTMBase64
//解密:
+ (NSData*) base64Decode:(NSString *)string
{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[4];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil) {
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true) {
if (ixtext >= lentext){
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= ‘A’) && (ch = ‘a’) && (ch = ’0′) && (ch ch = ch – ’0′ + 52;
} else if (ch == ‘+’) {
ch = 62;
} else if (ch == ‘=’) {
flendtext = true;
} else if (ch == ‘/’) {
ch = 63;
} else {
flignore = true;
}
if (!flignore) {
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext) {
if (ixinbuf == 0) {
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2)) {
ctcharsinbuf = 1;
} else {
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4) {
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0×30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0×03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++) {
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak) {
break;
}
}
}
return theData;
}
//加密:
+ (NSString*) base64Encode:(NSData *)data
{
static char base64EncodingTable[64] = {
‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’,
‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’,
‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’,
‘w’, ‘x’, ‘y’, ‘z’, ’0′, ’1′, ’2′, ’3′, ’4′, ’5′, ’6′, ’7′, ’8′, ’9′, ‘+’, ‘/’
};
int length = [data length];
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1)
return @”";
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext – ixtext;
if (ctremaining break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext) input[i] = raw[ix]; else input[i] = 0; } output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0×03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
[result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
for (i = ctcopy; i < 4; i++) [result appendString: @"="]; ixtext += 3; charsonline += 4; if ((length > 0) && (charsonline >= length))
charsonline = 0;
}
return result;
}
@end
用到的加密方法:EncryptUtil(DES加密)
#import “EncryptUtil.h”
#import “CommonCrypto/CommonCryptor.h”
#import “GTMBase64.h”
@implementation EncryptUtil
//DES加密
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
//DES解密
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
获取IP地址
+ (NSString *)localIPAddress
{
NSString *localIP = nil;
struct ifaddrs *addrs;
if (getifaddrs(&addrs)==0) {
const struct ifaddrs *cursor = addrs;
while (cursor != NULL) {
if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
{
//NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
//if ([name isEqualToString:@"en0"]) // Wi-Fi adapter
{
localIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)];
break;
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return localIP;
}
iOS base64加密解密
- |
- 浏览:2901
- |
- 更新:2013-05-17 12:12
-
从参考资料的地址中下载GTMBase64.zip库文件包,并解压,获得GTMBase64.h,GTMBase64.m和GTMDefines.h三个文件。
-
将解压得到的三个文件,添加到项目中。
-
新建一个base64的类,在base64.h中天假四个函数:
+ (NSString*)encodeBase64String:(NSString*)input;
+ (NSString*)decodeBase64String:(NSString*)input;
+ (NSString*)encodeBase64Data:(NSData*)data;
+ (NSString*)decodeBase64Data:(NSData*)data;
在base64.m文件中,实现上面4个函数:
+ (NSString*)encodeBase64String:(NSString* )input {
NSData*data = [inputdataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];
data = [GTMBase64encodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String;
}
+ (NSString*)decodeBase64String:(NSString* )input {
NSData*data = [inputdataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:YES];
data = [GTMBase64decodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String;
}
+ (NSString*)encodeBase64Data:(NSData*)data {
data = [GTMBase64encodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String;
}
+ (NSString*)decodeBase64Data:(NSData*)data {
data = [GTMBase64decodeData:data];
NSString*base64String = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding] ;
returnbase64String;
}
-
直接调用+ (NSString*)encodeBase64String:(NSString* )input和
+ (NSString*)decodeBase64String:(NSString* )input就可以进行加解密。
-
可以从参考资料的地址中下载dem
[iOS]AES加密在iOS上面的实现
Encryption.h文件
- //
- // Encryption.h
- // DownloadFile
- //
- // Created by zhoumin on 12-1-16.
- // Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- @class NSString;
- @interface NSData (Encryption)
- - (NSData *)AES256EncryptWithKey:(NSString *)key; //加密
- - (NSData *)AES256DecryptWithKey:(NSString *)key; //解密
- - (NSString *)newStringInBase64FromData; //追加64编码
- + (NSString*)base64encode:(NSString*)str; //同上64编码
- @end
Encryption.m文件
- //
- // Encryption.m
- // DownloadFile
- //
- // Created by on 12-1-16.
- // Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
- //
- #import "Encryption.h"
- #import <CommonCrypto/CommonCryptor.h>
- static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- @implementation NSData (Encryption)
- - (NSData *)AES256EncryptWithKey:(NSString *)key //加密
- {
- char keyPtr[kCCKeySizeAES256+1];
- bzero(keyPtr, sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
- NSUInteger dataLength = [self length];
- size_t bufferSize = dataLength + kCCBlockSizeAES128;
- void *buffer = malloc(bufferSize);
- size_t numBytesEncrypted = 0;
- CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
- kCCOptionPKCS7Padding | kCCOptionECBMode,
- keyPtr, kCCBlockSizeAES128,
- NULL,
- [self bytes], dataLength,
- buffer, bufferSize,
- &numBytesEncrypted);
- if (cryptStatus == kCCSuccess) {
- return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
- }
- free(buffer);
- return nil;
- }
- - (NSData *)AES256DecryptWithKey:(NSString *)key //解密
- {
- char keyPtr[kCCKeySizeAES256+1];
- bzero(keyPtr, sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
- NSUInteger dataLength = [self length];
- size_t bufferSize = dataLength + kCCBlockSizeAES128;
- void *buffer = malloc(bufferSize);
- size_t numBytesDecrypted = 0;
- CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
- kCCOptionPKCS7Padding | kCCOptionECBMode,
- keyPtr, kCCBlockSizeAES128,
- NULL,
- [self bytes], dataLength,
- buffer, bufferSize,
- &numBytesDecrypted);
- if (cryptStatus == kCCSuccess) {
- return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
- }
- free(buffer);
- return nil;
- }
- - (NSString *)newStringInBase64FromData //追加64编码
- {
- NSMutableString *dest = [[NSMutableString alloc] initWithString:@""];
- unsigned char * working = (unsigned char *)[self bytes];
- int srcLen = [self length];
- for (int i=0; i<srcLen; i += 3) {
- for (int nib=0; nib<4; nib++) {
- int byt = (nib == 0)?0:nib-1;
- int ix = (nib+1)*2;
- if (i+byt >= srcLen) break;
- unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F);
- if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F);
- [dest appendFormat:@"%c", base64[curr]];
- }
- }
- return dest;
- }
- + (NSString*)base64encode:(NSString*)str
- {
- if ([str length] == 0)
- return @"";
- const char *source = [str UTF8String];
- int strlength = strlen(source);
- char *characters = malloc(((strlength + 2) / 3) * 4);
- if (characters == NULL)
- return nil;
- NSUInteger length = 0;
- NSUInteger i = 0;
- while (i < strlength) {
- char buffer[3] = {0,0,0};
- short bufferLength = 0;
- while (bufferLength < 3 && i < strlength)
- buffer[bufferLength++] = source[i++];
- characters[length++] = base64[(buffer[0] & 0xFC) >> 2];
- characters[length++] = base64[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
- if (bufferLength > 1)
- characters[length++] = base64[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
- else characters[length++] = '=';
- if (bufferLength > 2)
- characters[length++] = base64[buffer[2] & 0x3F];
- else characters[length++] = '=';
- }
- NSString *g = [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease];
- return g;
- }
- @end
测试
- NSString *key = @"my password";
- NSString *secret = @"text to encrypt";
- //加密
- NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
- NSData *cipher = [plain AES256EncryptWithKey:key];
- NSLog(@"%@",[[cipher newStringInBase64FromData] autorelease]);
- printf("%s\n", [[cipher description] UTF8String]);
- NSLog(@"%@", [[[NSString alloc] initWithData:cipher encoding:NSUTF8StringEncoding] autorelease]);//打印出null,这是因为没有解密。
- //解密
- plain = [cipher AES256DecryptWithKey:key];
- printf("%s\n", [[plain description] UTF8String]);
- NSLog(@"%@", [[[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding] autorelease]);
- //打印出secret的内容,用密码解密过了。如果使用错误的密码,则打印null
demo下载:http://download.csdn.net/detail/z251257144/4820200
iOS代码加密常用加密方式
- |
- 浏览:85
- |
- 更新:2015-01-06 17:08
- |
- 标签: 加密
iOS代码加密常用加密方式,常见的iOS代码加密常用加密方式算法包括MD5加密、AES加密、BASE64加密,三大算法iOS代码加密是如何进行加密的,且看下文
MD5 iOS代码加密
-
MD5 iOS代码加密
创建MD5类,代码如下
#import <Foundation/Foundation.h>
@interface CJMD5 : NSObject
+(NSString *)md5HexDigest:(NSString *)input;
@end
-
#import "CJMD5.h"
#import <CommonCrypto/CommonDigest.h>
@implementation CJMD5
+(NSString *)md5HexDigest:(NSString *)input{
const char* str = [input UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH];
for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) {
[ret appendFormat:@"%02X",result];
}
return ret;
}
@end
-
MD5是不可逆的只有加密没有解密,iOS代码加密使用方式如下
NSString *userName = @"cerastes";
NSString *password = @"hello Word";
// MD5加密
NSString *md5 = [CJMD5 md5HexDigest:password];
NSLog(@"%@",md5);
END
AES加密iOS代码加密
-
AES加密iOS代码加密使用方法
// AES加密
NSString *encryptedData = [AESCrypt encrypt:userName password:password];//加密
NSString *message = [AESCrypt decrypt:encryptedData password:password]; //解密
NSLog(@"加密结果 = %@",encryptedData);
NSLog(@"解密结果 = %@",message);
END
BASE64加密iOS代码加密
-
BASE64加密iOS代码加密添加如下方法
.h
+ (NSString*)encodeBase64String:(NSString *)input;
+ (NSString*)decodeBase64String:(NSString *)input;
+ (NSString*)encodeBase64Data:(NSData *)data;
+ (NSString*)decodeBase64Data:(NSData *)data;
-
.m
+ (NSString*)encodeBase64String:(NSString * )input {
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
data = [GTMBase64 encodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return base64String;
}
+ (NSString*)decodeBase64String:(NSString * )input {
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
data = [GTMBase64 decodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return base64String;
}
+ (NSString*)encodeBase64Data:(NSData *)data {
data = [GTMBase64 encodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return base64String;
}
+ (NSString*)decodeBase64Data:(NSData *)data {
data = [GTMBase64 decodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return base64String;
}
-
BASE64加密iOS代码加密使用方法
// BASE64加密
NSString *baseEncodeString = [GTMBase64 encodeBase64String:password];
NSString *baseDecodeString = [GTMBase64 decodeBase64String:baseEncodeString];
NSLog(@"baseEncodeString = %@",baseEncodeString);
NSLog(@"baseDecodeString = %@",baseDecodeString);
END
iOS应用代码加密
-
除了以上的三种算法的iOS代码加密之外,iOS应用代码加密也是非常重要的,这里就不贴代码了,主要的iOS代码加密方式如下,iOS应用代码加密是 爱 加 密 平台提供的专业的iOS加密服务。
-
1)本地数据加密
对NSUserDefaults,sqlite存储文件数据加密,保护帐号和关键信息。
2)URL编码加密
对程序中出现的URL进行编码加密,防止URL被静态分析
3)网络传输数据加密
对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取
4)方法体,方法名高级混淆
对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码
5)程序结构混排加密
对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低。
IOS - CoreData 增删改查
#pragma mark - Core Data Methods
- (void)insertObjectWithFileName:(NSString *)fileName
{
/**
SQL新增记录的过程
1. 拼接一个INSERT的SQL语句
2. 执行SQL
*/
// 1. 实例化并让context“准备”将一条个人记录增加到数据库
ReaderDocument *document = [NSEntityDescription insertNewObjectForEntityForName:kOAPDFDocument inManagedObjectContext:self.managedObjectContext];
// 2. 设置个人信息
document.fileName = fileName;
// 3. 保存(让context保存当前的修改)
if ([self.managedObjectContext save:nil]) {
NSLog(@"新增成功");
} else {
NSLog(@"新增失败");
}
}
- (NSMutableArray *)getObjectsWithPredicate:(NSString *)predicate
{
// 1. 实例化一个查询(Fetch)请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:kOAPDFDocument];
// 3. 条件查询,通过谓词来实现的
// request.predicate = [NSPredicate predicateWithFormat:@"age < 60 && name LIKE '*五'"];
// 在谓词中CONTAINS类似于数据库的 LIKE '%王%'
// request.predicate = [NSPredicate predicateWithFormat:@"phoneNo CONTAINS '1'"];
// 如果要通过key path查询字段,需要使用%K
// request.predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS '1'", @"phoneNo"];
// 直接查询字表中的条件
// 2. 让_context执行查询数据
NSArray *array = [self.managedObjectContext executeFetchRequest:request error:nil];
// for (OAPDFDocument *pdf in array) {
// NSLog(@"\nfielName:%@ \nfilePath:%@ \nfileSize:%@", pdf.fileName, pdf.filePath, pdf.fileSize);
// 在CoreData中,查询是懒加载的
// 在CoreData本身的SQL查询中,是不使用JOIN的,不需要外键
// 这种方式的优点是:内存占用相对较小,但是磁盘读写的频率会较高
// for (Book *b in p.books) {
// NSLog(@"%@ %@ %@", b.name, b.price, b.author);
// }
// }
// for (Book *b in array) {
// NSLog(@"%@ %@ %@", b.name, b.price, b.author);
// }
return [NSMutableArray arrayWithArray:array];
}
- (void)editObjectsWithPredicate:(NSPredicate *)predicate withState:(NSNumber *)state
{
// 1. 实例化一个查询(Fetch)请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:kOAPDFDocument];
// 2. 条件查询,通过谓词来实现的
request.predicate = predicate;
// 在谓词中CONTAINS类似于数据库的 LIKE '%王%'
// request.predicate = [NSPredicate predicateWithFormat:@"phoneNo CONTAINS '1'"];
// 如果要通过key path查询字段,需要使用%K
// request.predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS '1'", @"phoneNo"];
// 直接查询字表中的条件
// 3. 让_context执行查询数据
NSArray *array = [self.managedObjectContext executeFetchRequest:request error:nil];
for (ReaderDocument *pdf in array) {
// 3.1修改公文阅读状态
pdf.fileTag = state;
// 3.2修改公文最新打开日期
NSFileManager* fileMngr = [NSFileManager defaultManager];
NSDictionary* attributes = [fileMngr attributesOfItemAtPath:pdf.fileURL error:nil];
pdf.lastOpen = (NSDate *)[attributes objectForKey:NSFileModificationDate];
// 3.3获取并保存,该文件的首页缩略图
UIImage *thumbImage = [pdf imageFromPDFWithDocumentRef:pdf.fileURL];
pdf.thumbImage = UIImagePNGRepresentation(thumbImage);
[self.collectionView reloadData];
break;
}
// 4. 通知_context修改数据是否成功
if ([self.managedObjectContext save:nil]) {
NSLog(@"修改成功");
} else {
NSLog(@"修改失败");
}
}
- (void)removeObjectsWithPredicate:(NSString *)predicate
{
// 1. 实例化查询请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:kOAPDFDocument];
// 2. 设置谓词条件
// request.predicate = [NSPredicate predicateWithFormat:@"name = '张老头'"];
request.predicate = [NSPredicate predicateWithFormat:predicate];
// 3. 由上下文查询数据
NSArray *result = [self.managedObjectContext executeFetchRequest:request error:nil];
// 4. 输出结果
for (ReaderDocument *pdf in result) {
// 删除一条记录
[self.managedObjectContext deleteObject:pdf];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:pdf.filePath];
if (fileExists) {
[self removeFileWithName:pdf.fileName];
}else{
NSLog(@"File:%@ is not exist!",pdf.fileName);
}
// break;
}
// 5. 通知_context保存数据
if ([self.managedObjectContext save:nil]) {
NSLog(@"删除%lu文件成功",(unsigned long)[result count]);
} else {
NSLog(@"删除失败");
}
}
- (void)removeFileWithName:(NSString *)fileName
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:fileName];
NSError *error;
BOOL success = [fileManager removeItemAtPath:filePath error:&error];
if (success) {
NSLog(@"Remove fiel:%@ Success!",fileName);
}
else
{
NSLog(@"Could not delete file -:%@ ",[error localizedDescription]);
}
}