2014-06-15 11:11:05 u010969412 阅读数 882
  • JavaScript之Date对象详解(属性和方法

    Date 对象属性 constructor 返回对创建此对象的 Date 函数的引用。 prototype 使您有能力向对象添加属性和方法。Date 对象方法 getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。 getFullYear() 从 Date 对象以四位数字返回年份。 getHours() 返回 Date 对象的小时 (0 ~ 23)。 getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。 getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。 getMonth() 从 Date 对象返回月份 (0 ~ 11)。 getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。 getTime() 返回 1970 年 1 月 1 日至今的毫秒数。 getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。 getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。 getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。 getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 getYear() 已废弃。 请使用 getFullYear() 方法代替。 parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。 setFullYear() 设置 Date 对象中的年份(四位数字)。 setHours() 设置 Date 对象中的小时 (0 ~ 23)。 setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。 setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。 setMonth() 设置 Date 对象中月份 (0 ~ 11)。 setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。 setTime() setTime() 方法以毫秒设置 Date 对象。 setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)。 setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 setUTCSeconds() setUTCSeconds() 方法用于根据世界时 (UTC) 设置指定时间的秒字段。 setYear() 已废弃。请使用 setFullYear() 方法代替。 toDateString() 把 Date 对象的日期部分转换为字符串。 toGMTString() 已废弃。请使用 toUTCString() 方法代替。 toISOString() 使用 ISO 标准返回字符串的日期格式。 toJSON() 以 JSON 数据格式返回日期字符串。 toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 toLocaleString() 据本地时间格式,把 Date 对象转换为字符串。 toString() 把 Date 对象转换为字符串。 toTimeString() 把 Date 对象的时间部分转换为字符串。 toUTCString() 根据世界时,把 Date 对象转换为字符串。 UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 valueOf() 返回 Date 对象的原始值。

    242 人正在学习 去看看 黄菊华

方法一:ios7.0之前适用

/**
 @method 获取指定宽度width,字体大小fontSize,字符串value的高度
 @param value 待计算的字符串
 @param fontSize 字体的大小
 @param Width 限制字符串显示区域的宽度
 @result float 返回的高度
 */
- (float) heightForString:(NSString *)value fontSize:(float)fontSize andWidth:(float)width
{
    CGSize sizeToFit = [value sizeWithFont:[UIFont systemFontOfSize:fontSize]
                         constrainedToSize:CGSizeMake(width -16.0, CGFLOAT_MAX)
                             lineBreakMode:NSLineBreakByWordWrapping];
        //此处的换行类型(lineBreakMode)可根据自己的实际情况进行设置
    return sizeToFit.height + 16.0;
}

方法二:ios7.0及之后适用

/**
 @method 获取指定宽度width,字体大小fontSize,字符串value的高度
 @param value 待计算的字符串
 @param fontSize 字体的大小
 @param Width 限制字符串显示区域的宽度
 @result float 返回的高度
 */
- (float) heightForString:(NSString *)value andWidth:(float)width{
    //获取当前文本的属性
    NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:value];
    _text.attributedText = attrStr;
    NSRange range = NSMakeRange(0, attrStr.length);
    // 获取该段attributedString的属性字典
    NSDictionary *dic = [attrStr attributesAtIndex:0 effectiveRange:&range];
    // 计算文本的大小
    CGSize sizeToFit = [value boundingRectWithSize:CGSizeMake(width - 16.0, MAXFLOAT) // 用于计算文本绘制时占据的矩形块
                                               options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading // 文本绘制时的附加选项
                                            attributes:dic        // 文字的属性
                                               context:nil].size; // context上下文。包括一些信息,例如如何调整字间距以及缩放。该对象包含的信息将用于文本绘制。该参数可为nil
    return sizeToFit.height + 16.0;
}

//注意:再前两种方法中,UITextView在上下左右分别有一个8pxpadding,需要将UITextView.contentSize.width减去16像素(左右的padding 2 x 8px)。同时返回的高度中再加上16像素(上下的padding),这样得到的才是UITextView真正适应内容的高度。如代码中 CGSizeMake(width -16.0, CGFLOAT_MAX)return sizeToFit.height + 16.0 UILable中则不用


方法三:通用(推荐)

/**
 @method 获取指定宽度width的字符串在UITextView上的高度
 @param textView 待计算的UITextView
 @param Width 限制字符串显示区域的宽度
 @result float 返回的高度
 */
- (float) heightForString:(UITextView *)textView andWidth:(float)width{
     CGSize sizeToFit = [textView sizeThatFits:CGSizeMake(width, MAXFLOAT)];
    return sizeToFit.height;
}


2016-04-30 10:31:19 iOS_wq 阅读数 10344
  • JavaScript之Date对象详解(属性和方法

    Date 对象属性 constructor 返回对创建此对象的 Date 函数的引用。 prototype 使您有能力向对象添加属性和方法。Date 对象方法 getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。 getFullYear() 从 Date 对象以四位数字返回年份。 getHours() 返回 Date 对象的小时 (0 ~ 23)。 getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。 getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。 getMonth() 从 Date 对象返回月份 (0 ~ 11)。 getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。 getTime() 返回 1970 年 1 月 1 日至今的毫秒数。 getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。 getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。 getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。 getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 getYear() 已废弃。 请使用 getFullYear() 方法代替。 parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。 setFullYear() 设置 Date 对象中的年份(四位数字)。 setHours() 设置 Date 对象中的小时 (0 ~ 23)。 setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。 setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。 setMonth() 设置 Date 对象中月份 (0 ~ 11)。 setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。 setTime() setTime() 方法以毫秒设置 Date 对象。 setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)。 setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 setUTCSeconds() setUTCSeconds() 方法用于根据世界时 (UTC) 设置指定时间的秒字段。 setYear() 已废弃。请使用 setFullYear() 方法代替。 toDateString() 把 Date 对象的日期部分转换为字符串。 toGMTString() 已废弃。请使用 toUTCString() 方法代替。 toISOString() 使用 ISO 标准返回字符串的日期格式。 toJSON() 以 JSON 数据格式返回日期字符串。 toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 toLocaleString() 据本地时间格式,把 Date 对象转换为字符串。 toString() 把 Date 对象转换为字符串。 toTimeString() 把 Date 对象的时间部分转换为字符串。 toUTCString() 根据世界时,把 Date 对象转换为字符串。 UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 valueOf() 返回 Date 对象的原始值。

    242 人正在学习 去看看 黄菊华

AFNetworking 3.0 版本使用

在Xcode7.0之后,苹果废弃了NSURLConnection方法,数据请求使用NSURLSession,作为网络请求类第三方库使用量最大的AFN也及时的更新的新的版本——AFN 3.0版本。新的版本的里废弃了基于NSURLConnection封装的AFHTTPRequestOperationManager,转而使用基于NSURLSession封装的AFHTTPSessionManager了。

下面将详细介绍AFN3.0的使用

1.cocoapods导入AFN 3.0

1.1 进入到工程目录下

$ cd 工程目录名

1.2 搜索最新的AFN库版本

$ pod search AFNetworking

1.3 创建podfile文件

$ vim podfile

1.4 按下键盘“i”键,输入如下的pod语句,然后按下“esc”键,退出编辑,再输入“:wq”,保存退出vim,项目根目录下就会新建我们需要的podfile文件

$ platform:ios,'7.0'
$ pod 'AFNetworking','~>3.1.0'

1.5 导入AFN库,使用如下语句导入和直接$ pod install的区别是略过cocoaPods的库更新过程,导入速度较快

$ pod install --verbose --no-repo-update

导入成功,使用后缀名为.xcworkspace的文件打开工程

2.配置plist文件

在Xcode 7.0之后,苹果使用了https的网路协议,所以在网络请求前,我们还需要配置一下工程的Info.plist文件

右键Info.plist文件  ->  open as ->  source code ,找到下图位置,粘贴如下代码

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>


3.使用AFN进行数据请求

3.1 请求管理类 (HttpsManager)

该类里都是+号方法,不是单例类

在.h里定义超时时间宏,以及成功和失败的block块

#define kTimeOutInterval 30 // 请求超时的时间
typedef void (^SuccessBlock)(NSDictionary *dict, BOOL success); // 访问成功block
typedef void (^AFNErrorBlock)(NSError *error); // 访问失败block

封装AFN请求管理者

#pragma mark - 创建请求者
+(AFHTTPSessionManager *)manager
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 超时时间
    manager.requestSerializer.timeoutInterval = kTimeOutInterval;
    
    // 声明上传的是json格式的参数,需要你和后台约定好,不然会出现后台无法获取到你上传的参数问题
    manager.requestSerializer = [AFHTTPRequestSerializer serializer]; // 上传普通格式
//    manager.requestSerializer = [AFJSONRequestSerializer serializer]; // 上传JSON格式
    
    // 声明获取到的数据格式
    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // AFN不会解析,数据是data,需要自己解析
//    manager.responseSerializer = [AFJSONResponseSerializer serializer]; // AFN会JSON解析返回的数据
    // 个人建议还是自己解析的比较好,有时接口返回的数据不合格会报3840错误,大致是AFN无法解析返回来的数据
    return manager;
}

3.2 get

+ (void)getUserCarShopAndSalesDataForSalesWithUserId:(NSString *)userId date:(NSString *)date selectAreaType:(NSString *)areaType Success:(SuccessBlock)success fail:(AFNErrorBlock)fail
{
    // get请求也可以直接将参数放在字典里,AFN会自己讲参数拼接在url的后面,不需要自己凭借
    NSDictionary *param = @{@"user_id":userId, @"sale_date":date, @"accessToken":@"e9c0e60318ebd07ec2fe", @"area_type":areaType};
    // 创建请求类
    AFHTTPSessionManager *manager = [self manager];
    [manager GET:@"http://pm.yunhan-china.com/index.php/Api_sale/sales_get" parameters:param progress:^(NSProgress * _Nonnull downloadProgress) {
        // 这里可以获取到目前数据请求的进度
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 请求成功
        if(responseObject){
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
            success(dict,YES);
        } else {
            success(@{@"msg":@"暂无数据"}, NO);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        // 请求失败
        fail(error);
    }];
}

3.3 post

+ (void)loginWithUserAccount:(NSString *)account password:(NSString *)password success:(SuccessBlock)success fail:(AFNErrorBlock)fail
{
    // 将请求参数放在请求的字典里
    NSDictionary *param = @{@"phoneNumber":account, @"password":@"f379eaf3c831b04de153469d1bec345e"};
    // 创建请求类
    AFHTTPSessionManager *manager = [self manager];
    [manager POST:@"http://pm.yunhan-china.com/index.php/api_common/login" parameters:param progress:^(NSProgress * _Nonnull uploadProgress) {
        // 这里可以获取到目前数据请求的进度
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 请求成功
        if(responseObject){
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
            success(dict,YES);
        } else {
            success(@{@"msg":@"暂无数据"}, NO);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        // 请求失败
        fail(error);
    }];
    
}

3.4 下载

- (void)downLoadWithUrlString:(NSString *)urlString
{
    // 1.创建管理者对象
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 2.设置请求的URL地址
    NSURL *url = [NSURL URLWithString:urlString];
    // 3.创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 4.下载任务
    NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        // 下载进度
        NSLog(@"当前下载进度为:%lf", 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        // 下载地址
        NSLog(@"默认下载地址%@",targetPath);
        // 设置下载路径,通过沙盒获取缓存地址,最后返回NSURL对象
        NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
        return [NSURL fileURLWithPath:filePath]; // 返回的是文件存放在本地沙盒的地址
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        // 下载完成调用的方法
        NSLog(@"%@---%@", response, filePath);
    }];
    // 5.启动下载任务
    [task resume];
}

3.5 上传

- (void)uploadWithUser:(NSString *)userId UrlString:(NSString *)urlString upImg:(UIImage *)upImg
{
    // 创建管理者对象
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 参数
    NSDictionary *param = @{@"user_id":userId};
    [manager POST:urlString parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        /******** 1.上传已经获取到的img *******/
        // 把图片转换成data
        NSData *data = UIImagePNGRepresentation(upImg);
        // 拼接数据到请求题中
        [formData appendPartWithFileData:data name:@"file" fileName:@"123.png" mimeType:@"image/png"];
        /******** 2.通过路径上传沙盒或系统相册里的图片 *****/
//        [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"文件地址"] name:@"file" fileName:@"1234.png" mimeType:@"application/octet-stream" error:nil];
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        // 打印上传进度
        NSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        //请求成功
        NSLog(@"请求成功:%@",responseObject);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //请求失败
        NSLog(@"请求失败:%@",error);
    }];
}

3.6 网络监听

- (void)AFNetworkStatus{
    
    //1.创建网络监测者
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    
    /*枚举里面四个状态  分别对应 未知 无网络 数据 WiFi
     typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
     AFNetworkReachabilityStatusUnknown          = -1,      未知
     AFNetworkReachabilityStatusNotReachable     = 0,       无网络
     AFNetworkReachabilityStatusReachableViaWWAN = 1,       蜂窝数据网络
     AFNetworkReachabilityStatusReachableViaWiFi = 2,       WiFi
     };
     */
    
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        //这里是监测到网络改变的block  可以写成switch方便
        //在里面可以随便写事件
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"未知网络状态");
                break;
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"无网络");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"蜂窝数据网");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"WiFi网络");
                
                break;
                
            default:
                break;
        }
        
    }] ;
}

OK,使用AFN 3.0 的使用就是这样子了!

谢谢大家!共同学习共同进步!


2015-10-31 15:26:02 u012352292 阅读数 382
  • JavaScript之Date对象详解(属性和方法

    Date 对象属性 constructor 返回对创建此对象的 Date 函数的引用。 prototype 使您有能力向对象添加属性和方法。Date 对象方法 getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。 getFullYear() 从 Date 对象以四位数字返回年份。 getHours() 返回 Date 对象的小时 (0 ~ 23)。 getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。 getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。 getMonth() 从 Date 对象返回月份 (0 ~ 11)。 getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。 getTime() 返回 1970 年 1 月 1 日至今的毫秒数。 getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。 getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。 getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。 getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 getYear() 已废弃。 请使用 getFullYear() 方法代替。 parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。 setFullYear() 设置 Date 对象中的年份(四位数字)。 setHours() 设置 Date 对象中的小时 (0 ~ 23)。 setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。 setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。 setMonth() 设置 Date 对象中月份 (0 ~ 11)。 setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。 setTime() setTime() 方法以毫秒设置 Date 对象。 setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)。 setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 setUTCSeconds() setUTCSeconds() 方法用于根据世界时 (UTC) 设置指定时间的秒字段。 setYear() 已废弃。请使用 setFullYear() 方法代替。 toDateString() 把 Date 对象的日期部分转换为字符串。 toGMTString() 已废弃。请使用 toUTCString() 方法代替。 toISOString() 使用 ISO 标准返回字符串的日期格式。 toJSON() 以 JSON 数据格式返回日期字符串。 toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 toLocaleString() 据本地时间格式,把 Date 对象转换为字符串。 toString() 把 Date 对象转换为字符串。 toTimeString() 把 Date 对象的时间部分转换为字符串。 toUTCString() 根据世界时,把 Date 对象转换为字符串。 UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 valueOf() 返回 Date 对象的原始值。

    242 人正在学习 去看看 黄菊华

     在iOS 8之后,UIAlertView和UIActionSheet方法都废弃了,在XCode7.0版本之前还不会提示,在7.0之后的版本这俩者会报红提示方法废弃。

"UIActionSheet is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleActionSheet instead"

"UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead"

      在苹果的文档中,代替倆者的方法是UIAlertController。

      UIAlertController有俩种 preferredStyle,分别是UIAlertControllerStyleActionSheet和UIAlertControllerStyleAlert。这俩种方式代表俩种不同的布局分别对应之前的ActionSheet和AlertView。

      创建初始化AlertController:

UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"1" message:@"1" preferredStyle:UIAlertControllerStyleActionSheet];

[self.navigationController presentViewController:alertC animated:YES completion:nil];



2016-09-08 10:23:29 autom_lishun 阅读数 3585
  • JavaScript之Date对象详解(属性和方法

    Date 对象属性 constructor 返回对创建此对象的 Date 函数的引用。 prototype 使您有能力向对象添加属性和方法。Date 对象方法 getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。 getFullYear() 从 Date 对象以四位数字返回年份。 getHours() 返回 Date 对象的小时 (0 ~ 23)。 getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。 getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。 getMonth() 从 Date 对象返回月份 (0 ~ 11)。 getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。 getTime() 返回 1970 年 1 月 1 日至今的毫秒数。 getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。 getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。 getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。 getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 getYear() 已废弃。 请使用 getFullYear() 方法代替。 parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。 setFullYear() 设置 Date 对象中的年份(四位数字)。 setHours() 设置 Date 对象中的小时 (0 ~ 23)。 setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。 setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。 setMonth() 设置 Date 对象中月份 (0 ~ 11)。 setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。 setTime() setTime() 方法以毫秒设置 Date 对象。 setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)。 setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 setUTCSeconds() setUTCSeconds() 方法用于根据世界时 (UTC) 设置指定时间的秒字段。 setYear() 已废弃。请使用 setFullYear() 方法代替。 toDateString() 把 Date 对象的日期部分转换为字符串。 toGMTString() 已废弃。请使用 toUTCString() 方法代替。 toISOString() 使用 ISO 标准返回字符串的日期格式。 toJSON() 以 JSON 数据格式返回日期字符串。 toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 toLocaleString() 据本地时间格式,把 Date 对象转换为字符串。 toString() 把 Date 对象转换为字符串。 toTimeString() 把 Date 对象的时间部分转换为字符串。 toUTCString() 根据世界时,把 Date 对象转换为字符串。 UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 valueOf() 返回 Date 对象的原始值。

    242 人正在学习 去看看 黄菊华

首先是关于关于IOS微信的支付分享或登录   成功调起客户端操作之后,返回你的应用之后onResp:方法不被执行的问题。


//这里说明一下,上次的集成告诉大家在Appdelegate.m里加入如下两个方法,并完成对Wxi的delegate的设置。这两个方法在官方的文档上注明了IOS9.0之后废弃(但其实9.1好像也能用),不管怎样,如果你是Xcode7.2,或者IOS9.2的话,可能会遇见在微信客户端操作返回程序之后不能执行微信的onResp回调方法的问题,就是因为一下这两个方法被废弃掉了,所以我的新demo替换了一个新的方法在下面。就完美解决这个问题了(并不建议删除这两个方法,新方法是9.0以后的方法,可能系统低版本的用户不支持。所以我三种方法都留下了,如果有人发现不能都留下的话,请简信告诉我一下,再次谢过了

//被废弃的方法如下

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;


-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication

annotation:(id)annotation;


//替换的新方法

改用方法为- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options;


这些更新都可以在这篇文章上的demo里看到,另外,新的demo里我还新增了IOS的三方分享和三方登录的集成。这样这个demo里就基本完成了三方支付、分享、登录的统一集成。点击这里查看新demo ,所有的集成方法和步骤我都写在readme那个word里了,如果还有其他问题欢迎在评论里问我,希望能帮到你们。

2015-08-09 11:47:06 u013020103 阅读数 1742
  • JavaScript之Date对象详解(属性和方法

    Date 对象属性 constructor 返回对创建此对象的 Date 函数的引用。 prototype 使您有能力向对象添加属性和方法。Date 对象方法 getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。 getFullYear() 从 Date 对象以四位数字返回年份。 getHours() 返回 Date 对象的小时 (0 ~ 23)。 getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。 getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。 getMonth() 从 Date 对象返回月份 (0 ~ 11)。 getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。 getTime() 返回 1970 年 1 月 1 日至今的毫秒数。 getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。 getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。 getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。 getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 getYear() 已废弃。 请使用 getFullYear() 方法代替。 parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。 setFullYear() 设置 Date 对象中的年份(四位数字)。 setHours() 设置 Date 对象中的小时 (0 ~ 23)。 setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。 setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。 setMonth() 设置 Date 对象中月份 (0 ~ 11)。 setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。 setTime() setTime() 方法以毫秒设置 Date 对象。 setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)。 setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 setUTCSeconds() setUTCSeconds() 方法用于根据世界时 (UTC) 设置指定时间的秒字段。 setYear() 已废弃。请使用 setFullYear() 方法代替。 toDateString() 把 Date 对象的日期部分转换为字符串。 toGMTString() 已废弃。请使用 toUTCString() 方法代替。 toISOString() 使用 ISO 标准返回字符串的日期格式。 toJSON() 以 JSON 数据格式返回日期字符串。 toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 toLocaleString() 据本地时间格式,把 Date 对象转换为字符串。 toString() 把 Date 对象转换为字符串。 toTimeString() 把 Date 对象的时间部分转换为字符串。 toUTCString() 根据世界时,把 Date 对象转换为字符串。 UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 valueOf() 返回 Date 对象的原始值。

    242 人正在学习 去看看 黄菊华

历史:

1) iOS 5.0以前,iOS 2.0版本以后UIDevice提供一个获取设备唯一标识符的方法uniqueIdentifier,因为该唯一标识符与手机一一对应,苹果觉得可能会泄露用户隐私,所以在 iOS 5.0之后该方法就被废弃掉了。

2)iOS 6.0系统新增了两个用于替换uniqueIdentifier的接口,分别是:identifierForVendor,advertisingIdentifier。

但是APP删除重装后会变化,所以使用WiFi的mac地址来取代已经废弃了的uniqueIdentifier方法。具体的方法晚上有很多,大家感兴趣的可以自己找找,这儿提供一个网址: http://stackoverflow.com/questions/677530/how-can-i-programmatically-get-the-mac-address-of-an-iphone

3)iOS 7中苹果再一次无情的封杀mac地址,使用之前的方法获取到的mac地址全部都变成了02:00:00:00:00:00。有问题总的解决啊,于是四处查资料,终于有了思路是否可以使用KeyChain来保存获取到的唯一标示符呢,这样以后即使APP删了再装回来,也可以从KeyChain中读取回来。

OK 正题来了。。。

KeyChain介绍

  我们搞iOS开发,一定都知道OS X里面的KeyChain(钥匙串),通常要乡镇及调试的话,都得安装证书之类的,这些证书就是保存在KeyChain中,还有我们平时浏览网页记录的账号密码也都是记录在KeyChain中。iOS中的KeyChain相比OS X比较简单,整个系统只有一个KeyChain,每个程序都可以往KeyChain中记录数据,而且只能读取到自己程序记录在KeyChain中的数据。iOS中Security.framework框架提供了四个主要的方法来操作KeyChain:

复制代码

// 查询
OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result);

// 添加
OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result);

// 更新KeyChain中的Item
OSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate);

// 删除KeyChain中的Item
OSStatus SecItemDelete(CFDictionaryRef query)
复制代码

  这四个方法参数比较复杂,一旦传错就会导致操作KeyChain失败,这块儿文档中介绍的比较详细,大家可以查查官方文档Keychain Services Reference。

  前面提到了每个APP只允许访问自己在KeyChain中记录的数据,那么是不是就没有别的办法访问其他APP存在KeyChain的数据了?

  苹果提供了一个方法允许同一个发商的多个APP访问各APP之间的途径,即在调SecItemAdd添加数据的时候指定AccessGroup,即访问组。一个APP可以属于同事属于多个分组,添加KeyChain数据访问组需要做一下两件事情:

  a、在APP target的bulibSetting里面设置Code Signing Entitlements,指向包含AceessGroup的分组信息的plist文件。该文件必须和工程文件在同一个目录下,我在添加访问分组的时候就因为plist文件位置问题,操作KeyChain失败,查找这个问题还花了好久的时间。

  b、在工程目录下新建一个KeychainAccessGroups.plist文件,该文件的结构中最顶层的节点必须是一个名为“keychain-access-groups”的Array,并且该Array中每一项都是一个描述分组的NSString。对于String的格式也有相应要求,格式为:”AppIdentifier.com.*“,其中APPIdentifier就是你的开发者帐号对应的ID。

  c、在代码中往KeyChain中Add数据的时候,设置kSecAttrAccessGroup,代码如下:

复制代码

   NSString *accessGroup = [NSString stringWithUTF8String:”APPIdentifier.com.cnblogs.smileEvday”];
if (accessGroup != nil)
{

if TARGET_IPHONE_SIMULATOR

    // Ignore the access group if running on the iPhone simulator.
    //
    // Apps that are built for the simulator aren't signed, so there's no keychain access group
    // for the simulator to check. This means that all apps can see all keychain items when run
    // on the simulator.
    //
    // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
    // simulator will return -25243 (errSecNoAccessForItem).

else

    [dictForQuery setObject:accessGroup forKey:(id)kSecAttrAccessGroup];

endif

}

复制代码

  这段代码是从官方的Demo中直接拷贝过来的,根据注释我们可以看到,模拟器是不支持AccessGroup的,所以才行了预编译宏来选择性添加。

  注:appIdentifer就是开发者帐号的那一串标识,如下图所示:

  打开xcode的Organizer,选择Device选项卡,连接设备就可以看到设备上安装的开发者账号描述文件列表,其中第五列最开始的10个字符即为App Identifier,这块儿前面写的不是很清楚,好多朋友加我qq问我,今天特地补上。

三、使用KeyChain保存和获取UDID

  说了这么多终于进入正题了,如何在iOS 7上面获取到不变的UDID。我们将第二部分所讲的知识直接应用进来就可以了轻松达到我们要的效果了,下面我们先看看往如何将获取到的identifierForVendor添加到KeyChain中的代码。

复制代码

  • (BOOL)settUDIDToKeyChain:(NSString*)udid
    {
    NSMutableDictionary *dictForAdd = [[NSMutableDictionary alloc] init];

    [dictForAdd setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
    [dictForAdd setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier] forKey:kSecAttrDescription];

    [dictForAdd setValue:@”UUID” forKey:(id)kSecAttrGeneric];
    // Default attributes for keychain item.
    [dictForAdd setObject:@”” forKey:(id)kSecAttrAccount];
    [dictForAdd setObject:@”” forKey:(id)kSecAttrLabel];
    // The keychain access group attribute determines if this item can be shared // amongst multiple apps whose code signing entitlements contain the same keychain access group.
    NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup]; if (accessGroup != nil)
    {#if TARGET_IPHONE_SIMULATOR // Ignore the access group if running on the iPhone simulator. //
    // Apps that are built for the simulator aren’t signed, so there’s no keychain access group // for the simulator to check. This means that all apps can see all keychain items when run // on the simulator. //
    // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the // simulator will return -25243 (errSecNoAccessForItem).#else
    [dictForAdd setObject:accessGroup forKey:(id)kSecAttrAccessGroup];#endif
    } const char *udidStr = [udid UTF8String];
    NSData *keyChainItemValue = [NSData dataWithBytes:udidStr length:strlen(udidStr)];
    [dictForAdd setValue:keyChainItemValue forKey:(id)kSecValueData];

    OSStatus writeErr = noErr; if ([SvUDIDTools getUDIDFromKeyChain]) { // there is item in keychain [SvUDIDTools updateUDIDInKeyChain:udid];
    [dictForAdd release]; return YES;
    } else { // add item to keychain
    writeErr = SecItemAdd((CFDictionaryRef)dictForAdd, NULL); if (writeErr != errSecSuccess) {
    NSLog(@”Add KeyChain Item Error!!! Error Code:%ld”, writeErr);

        [dictForAdd release];            return NO;
    }        else {
        NSLog(@"Add KeyChain Item Success!!!");
        [dictForAdd release];            return YES;
    }
    

    }

    [dictForAdd release]; return NO;
    }
    复制代码

      上面代码中,首先构建一个要添加到KeyChain中数据的Dictionary,包含一些基本的KeyChain Item的数据类型,描述,访问分组以及最重要的数据等信息,最后通过调用SecItemAdd方法将我们需要保存的UUID保存到KeyChain中。

      获取KeyChain中相应数据的代码如下:

复制代码

  • (NSString*)getUDIDFromKeyChain
    {
    NSMutableDictionary *dictForQuery = [[NSMutableDictionary alloc] init];
    [dictForQuery setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
    // set Attr Description for query [dictForQuery setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier]
    forKey:kSecAttrDescription];
    // set Attr Identity for query
    NSData *keychainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier
    length:strlen(kKeychainUDIDItemIdentifier)];
    [dictForQuery setObject:keychainItemID forKey:(id)kSecAttrGeneric];
    // The keychain access group attribute determines if this item can be shared // amongst multiple apps whose code signing entitlements contain the same keychain access group.
    NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup]; if (accessGroup != nil)
    {#if TARGET_IPHONE_SIMULATOR // Ignore the access group if running on the iPhone simulator. //
    // Apps that are built for the simulator aren’t signed, so there’s no keychain access group // for the simulator to check. This means that all apps can see all keychain items when run // on the simulator. //
    // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the // simulator will return -25243 (errSecNoAccessForItem).#else
    [dictForQuery setObject:accessGroup forKey:(id)kSecAttrAccessGroup];#endif
    }

    [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecMatchCaseInsensitive];
    [dictForQuery setValue:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
    [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnData];

    OSStatus queryErr = noErr;
    NSData *udidValue = nil;
    NSString *udid = nil;
    queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, (CFTypeRef*)&udidValue);

    NSMutableDictionary *dict = nil;
    [dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
    queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, (CFTypeRef*)&dict);
    if (queryErr == errSecItemNotFound) {
    NSLog(@”KeyChain Item: %@ not found!!!”, [NSString stringWithUTF8String:kKeychainUDIDItemIdentifier]);
    } else if (queryErr != errSecSuccess) {
    NSLog(@”KeyChain Item query Error!!! Error code:%ld”, queryErr);
    } if (queryErr == errSecSuccess) {
    NSLog(@”KeyChain Item: %@”, udidValue);
    if (udidValue) {
    udid = [NSString stringWithUTF8String:udidValue.bytes];
    }
    }

    [dictForQuery release]; return udid;
    }
    复制代码

      上面代码的流程也差不多一样,首先创建一个Dictionary,其中设置一下查找条件,然后通过SecItemCopyMatching方法获取到我们之前保存到KeyChain中的数据。

四、总结

  本文介绍了使用KeyChain实现APP删除后依然可以获取到相同的UDID信息的解决方法。

  你可能有疑问,如果系统升级以后,是否仍然可以获取到之前记录的UDID数据?

  答案是肯定的,这一点我专门做了测试。就算我们程序删除掉,系统经过升级以后再安装回来,依旧可以获取到与之前一致的UDID。但是当我们把整个系统还原以后是否还能获取到之前记录的UDID,这一点我觉得应该不行,不过手机里面数据太多,没有测试,如果大家有兴趣可以测试一下,验证一下我的猜想。

  完整代码地址: https://github.com/smileEvday/SvUDID

  大家如果要在真机运行时,需要替换两个地方:

  第一个地方是plist文件中的accessGroup中的APPIdentifier。

  第二个地方是SvUDIDTools.m中的kKeyChainUDIDAccessGroup的APPIdentity为你所使用的profile的APPIdentifier。

  文章和代码中如果有什么不对的地方,欢迎指正,在这儿先谢过了。

文章由一片枫叶的博客修改而来

UILabel自适应

阅读数 161

没有更多推荐了,返回首页