iOS开发中的一些常用小技巧

==========================================================================================================

获得app的版本号和名称以及检查更新版本提示

一. 获取版本号和应用名称

线上app都有一个版本号,我们也经常会发现在设置中会有一个当前应用的版本号

iOS的版本号,一个叫做Version,一个叫做Build,这两个值都可以在Xcode 中选中target,点击General后看到。 Version在plist文件中的key是“CFBundleShortVersionString”,和AppStore上的版本号保持一致,Build在plist中的key是“CFBundleVersion”,代表build的版本号。

如何用代码获得这个版本号呢?

代码实现获得应用的Verison号:

[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];

获得build号:
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]

顺便加一个获取app名称的代码:

 NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];  

  1. 二.版本检查更新

-(void)getUpdate

{

    NSDictionary *infoDict = [[NSBundlemainBundleinfoDictionary];

    NSString *nowVersion = [infoDictobjectForKey:@"CFBundleVersion"];

   

    NSURL url = [NSURLURLWithString:@"http://itunes.apple.com/lookup?id=*******"];

    NSString * file =  [NSStringstringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

    //"version":"1.0"

    NSRange substr = [file rangeOfString:@"\"version\":\""];

    NSRange range1 = NSMakeRange(substr.location+substr.length,10);

    NSRange substr2 =[file rangeOfString:@"\"" options:NULL range:range1];

    NSRange range2 = NSMakeRange(substr.location+substr.length, substr2.location-substr.location-substr.length);

    NSString *newVersion =[filesubstringWithRange:range2];

    if([nowVersion isEqualToString:newVersion]==NO)

    {

        UIAlertView *alert = [[UIAlertViewallocinitWithTitle:nilmessage:@"版本有更新"delegate:selfcancelButtonTitle:@"取消"otherButtonTitles:@"更新",nil];

       [alert show];

       [alert release];

    } else {

       UIAlertView *alert = [[UIAlertViewallocinitWithTitle:nilmessage:@"已是最新版本"delegate:selfcancelButtonTitle:@"确定"otherButtonTitles:nil];

       [alert show];

       [alert release];

    }

   

}

- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

    if(buttonIndex==1)

{

     //link地址,下载地址

       NSURL url = [NSURLURLWithString:@"https://itunes.apple.com/us/app/***-***-***/id*******?ls=1&mt=8"];

       [[UIApplication sharedApplication]openURL:url];

    }

}


=========================================================================================================


1. 判断手机号码格式是否正确,利用正则表达式验证

- (BOOL)valiMobile:(NSString *)mobile

{

    mobile = [mobile stringByReplacingOccurrencesOfString:@" "withString:@""];

    if (mobile.length !=11)

    {

        returnNO;

    }else{

        /**

         * 移动号段正则表达式

         */

        NSString *CM_NUM =@"^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";

        /**

         * 联通号段正则表达式

         */

        NSString *CU_NUM =@"^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";

        /**

         * 电信号段正则表达式

         */

        NSString *CT_NUM =@"^((133)|(153)|(177)|(18[0,1,9]))\\d{8}$";

        NSPredicate *pred1 = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", CM_NUM];

        BOOL isMatch1 = [pred1evaluateWithObject:mobile];

        NSPredicate *pred2 = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", CU_NUM];

        BOOL isMatch2 = [pred2evaluateWithObject:mobile];

        NSPredicate *pred3 = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", CT_NUM];

        BOOL isMatch3 = [pred3evaluateWithObject:mobile];

        

        if (isMatch1 || isMatch2 || isMatch3) {

            returnYES;

        }else{

            returnNO;

        }

    }

}


2. 判断邮箱格式是否正确,利用正则表达式验证

+ (BOOL)isAvailableEmail:(NSString *)email
{
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:email];
}

3. 让iOS应用直接退出
+ (void)backOutApp {
    UIWindow *window = [[UIApplication sharedApplication].delegate window];
    [UIView animateWithDuration:1.0f animations:^{
        window.alpha = 0;
    } completion:^(BOOL finished) {
        exit(0);
    }];
}
4. NSArray 快速求总和、最大值、最小值、平均值
+ (NSString *)caculateArray:(NSArray *)array
{
    CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
    CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
    CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue];
    CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue];
    NSLog(@"%fn%fn%fn%f",sum,avg,max,min);
    return [NSString stringWithFormat:@"%f",sum];
}
5. 验证身份证
+ (BOOL)checkIdentityCardNo:(NSString*)value {
    value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSInteger length =0;
    if (!value) {
        return NO;
    }else {
        length = value.length;
        if (length !=15 && length !=18) {
            return NO;
        }
    }
    // 省份代码
    NSArray *areasArray =@[@"11",@"12", @"13",@"14", @"15",@"21", @"22",@"23", @"31",@"32", @"33",@"34", @"35",@"36", @"37",@"41", @"42",@"43", @"44",@"45", @"46",@"50", @"51",@"52", @"53",@"54", @"61",@"62", @"63",@"64", @"65",@"71", @"81",@"82", @"91"];
    NSString *valueStart2 = [value substringToIndex:2];
    BOOL areaFlag =NO;
    for (NSString *areaCode in areasArray) {
        if ([areaCode isEqualToString:valueStart2]) {
            areaFlag =YES;
            break;
        }
    }
    if (!areaFlag) {
        return false;
    }
    NSRegularExpression *regularExpression;
    NSUInteger numberofMatch;
    NSInteger year =0;
    switch (length) {
        case 15:
            year = [[value substringWithRange:NSMakeRange(6,2)] integerValue] +1900;
            if (year %4 ==0 || (year 0 ==0 && year %4 ==0)) {
                regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$"
                                                                       options:NSRegularExpressionCaseInsensitive
                                                                         error:nil];//测试出生日期的合法性
            }else {
                regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$"
                                                                       options:NSRegularExpressionCaseInsensitive
                                                                         error:nil];//测试出生日期的合法性
            }
            numberofMatch = [regularExpression numberOfMatchesInString:value                                                 options:NSMatchingReportProgress
                           range:NSMakeRange(0, value.length)];
            if(numberofMatch >0) {
                return YES;
            }else {
                return NO;
            }
        case 18:
            year = [value substringWithRange:NSMakeRange(6,4)].intValue;
            if (year %4 ==0 || (year 0 ==0 && year %4 ==0)) {
                regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$"
options:NSRegularExpressionCaseInsensitive                                                                     error:nil];//测试出生日期的合法性
            }else {
                regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$"                                                                      options:NSRegularExpressionCaseInsensitive                                                                     error:nil];//测试出生日期的合法性
            }
            numberofMatch = [regularExpression numberOfMatchesInString:value                                                 options:NSMatchingReportProgress                                                     range:NSMakeRange(0, value.length)];
            if(numberofMatch >0) {
                int S = ([value substringWithRange:NSMakeRange(0,1)].intValue + [value substringWithRange:NSMakeRange(10,1)].intValue) *7 + ([value substringWithRange:NSMakeRange(1,1)].intValue + [value substringWithRange:NSMakeRange(11,1)].intValue) *9 + ([value substringWithRange:NSMakeRange(2,1)].intValue + [value substringWithRange:NSMakeRange(12,1)].intValue) *10 + ([value substringWithRange:NSMakeRange(3,1)].intValue + [value substringWithRange:NSMakeRange(13,1)].intValue) *5 + ([value substringWithRange:NSMakeRange(4,1)].intValue + [value substringWithRange:NSMakeRange(14,1)].intValue) *8 + ([value substringWithRange:NSMakeRange(5,1)].intValue + [value substringWithRange:NSMakeRange(15,1)].intValue) *4 + ([value substringWithRange:NSMakeRange(6,1)].intValue + [value substringWithRange:NSMakeRange(16,1)].intValue) *2 + [value substringWithRange:NSMakeRange(7,1)].intValue *1 + [value substringWithRange:NSMakeRange(8,1)].intValue *6 + [value substringWithRange:NSMakeRange(9,1)].intValue *3;
                int Y = S ;
                NSString *M =@"F";
                NSString *JYM =@"10X98765432";
                M = [JYM substringWithRange:NSMakeRange(Y,1)];// 判断校验位
                if ([M isEqualToString:[value substringWithRange:NSMakeRange(17,1)]]) {
                    return YES;// 检测ID的校验位
                }else {
                    return NO;
                }
            }else {
                return NO;
            }
        default:
            return false;
    }
}

6.设置按钮边框(颜色、边界宽度)

        CGColorSpaceRef colorSpaceRef =CGColorSpaceCreateDeviceRGB();

        CGColorRef color =CGColorCreate(colorSpaceRef, (CGFloat[]){172.0/255.0,172.0/255.0,172.0/255.0,1});

        [dazhe1.layersetBorderColor:color];

        [dazhe1.layersetMasksToBounds:YES];

        [dazhe1.layersetBorderWidth:0.5];

7.程序内调用safari跳转URL链接

一定要加http!!!

NSString *urlString =@"http://www.baidu.com";

[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:urlString]];

8.获取当前设备的唯一标识

    NSUUID *identifierForVendor = [[UIDevicecurrentDevice]identifierForVendor];

    NSString *deviceId = [identifierForVendorUUIDString];

9. Release 模式下禁用 NSLog

因为NSLog的输出还是比较消耗系统资源的,而且输出的数据也可能会暴露出App里的保密数据,所以发布正式版时需要把这些输出全部屏蔽掉。

我们可以在发布版本前先把所有NSLog语句注释掉,等以后要调试时,再取消这些注释,这实在是一件无趣而耗时的事!还好,还有更优雅的解决方法,就是在项目的prefix.pch文件里加入下面一段代码,加入后,NSLog就只在Debug下有输出,Release下不输出了。

#ifndef __OPTIMIZE__

#define NSLog(...) NSLog(__VA_ARGS__)

#else

#define NSLog(...) {}

#endif

10.UIImage转NSData 字符串转CLLocationDegrees

 NSData *imageData =UIImageJPEGRepresentation([selfimageWithImageSimple:resultscaledToSize:CGSizeMake(200,200)],0.5);

 CLLocationDegrees latitude = [self.latLngDic[@"lat"]doubleValue];

 CLLocationDegrees longitude = [self.latLngDic[@"lng"]doubleValue];


11.xib添加约束以后,添加动画没有效果

只需要在修改约束后面紧跟着调用[父控件.view layoutIfNeeded];就可以了。

12.动画(弹簧效果)

//    [UIView animateWithDuration:0.5 delay:1 options:UIViewAnimationOptionLayoutSubviews animations:^{

//        self.iconImageView.transform = CGAffineTransformMakeScale(4.5, 4.5);

//    } completion:^(BOOL finished) {

//        [UIView animateWithDuration:0.1 animations:^{

//            self.iconImageView.transform = CGAffineTransformMakeScale(4, 4);

//        } completion:^(BOOL finished) {

//            [UIView animateWithDuration:0.1 animations:^{

//                self.iconImageView.transform = CGAffineTransformMakeScale(3.8, 3.8);

//            } completion:^(BOOL finished) {

//                [UIView animateWithDuration:0.1 animations:^{

//                    self.iconImageView.transform = CGAffineTransformMakeScale(4, 4);

//                } completion:^(BOOL finished) {

//                    [UIView animateWithDuration:0.1 animations:^{

//                        self.iconImageView.transform = CGAffineTransformMakeScale(3.8, 3.8);

//                    } completion:^(BOOL finished) {

//                        [UIView animateWithDuration:0.1 animations:^{

//                            self.iconImageView.transform = CGAffineTransformMakeScale(3.9, 3.9);

//                        } completion:^(BOOL finished) {

//                            

//                        }];

//

//                    }];

//

//                }];

//

//            }];

//

//        }];

//    }];

正解:

    [UIViewanimateWithDuration:0.5delay:1usingSpringWithDamping:0.4initialSpringVelocity:2.0options:UIViewAnimationOptionCurveEaseOutanimations:^{

        self.iconImageView.transform = CGAffineTransformMakeScale(4.5,4.5);

    } completion:^(BOOL finished) {

        

    }];

12.生成随机色

    movieCell.backgroundColor = [UIColorcolorWithRed:arc4random_uniform(255)/255.0green:arc4random_uniform(255)/255.0blue:arc4random_uniform(255)/255.0alpha:1];

13.对单个页面隐藏状态栏

- (BOOL)prefersStatusBarHidden {

    returnYES;

}

14.数组倒序排列

 _dataArray=[[NSMutableArray alloc]init];

 [_dataArray addObjectsFromArray:[messageInfoDict objectForKey:@"payMessage"]];

//如果数组中装的是1,2,3,4经过reverseObjectEnumerator处理后,数组中各个元素会倒序排列,结果为4,3,2,1.

  _dataArray=(NSMutableArray *)[[_dataArrayreverseObjectEnumerator] allObjects];

15.更改进度条高度

    //进度条

    UIProgressView *progressView = [[UIProgressViewalloc]initWithFrame:CGRectMake(0,self.glkView.frame.size.height+64,VIEW_WIDTH,5)];

    self.progressView = progressView;

    self.progressView.trackTintColor =Color(217,217,217);//设置它的轨道颜色

    self.progressView.progressTintColor =Color(158,194,24);//设置进度的颜色

    self.progressView.transform = CGAffineTransformMakeScale(1.0f,3.0f);//更改进度条高度

    [self.viewaddSubview:progressView];

16.按钮上图下字样式实现
  1. -(void)initButton:(UIButton*)btn{  
  2.     btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;//使图片和文字水平居中显示  
  3.     [btn setTitleEdgeInsets:UIEdgeInsetsMake(btn.imageView.frame.size.height ,-btn.imageView.frame.size.width0.0,0.0)];//文字距离上边框的距离增加imageView的高度,距离左边框减少imageView的宽度,距离下边框和右边框距离不变  
  4.     [btn setImageEdgeInsets:UIEdgeInsetsMake(0.00.0,0.0, -btn.titleLabel.bounds.size.width)];//图片距离右边框距离减少图片的宽度,其它不边  

17.将View的内容转变为Image

-(UIImage *)getImageFromView:(UIView *)theView

{

//UIGraphicsBeginImageContext(theView.bounds.size);

UIGraphicsBeginImageContextWithOptions(theView.bounds.sizeYES, theView.layer.contentsScale);

[theView.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *image=UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return image;

}

18.获取当前屏幕显示的viewcontroller

- (UIViewController *)showCurrentVC

{

    UIWindow * window = [[UIApplicationsharedApplication]keyWindow];

    if (window.windowLevel !=UIWindowLevelNormal){

        NSArray *windows = [[UIApplicationsharedApplication]windows];

        for(UIWindow * tmpWinin windows){

            if (tmpWin.windowLevel ==UIWindowLevelNormal){

                window = tmpWin;

                break;

            }

        }

    }

    UIViewController *result = window.rootViewController;

    while (result.presentedViewController) {

        result = result.presentedViewController;

    }

    if ([resultisKindOfClass:[UITabBarControllerclass]]) {

        result = [(UITabBarController *)resultselectedViewController];

    }

    if ([resultisKindOfClass:[UINavigationControllerclass]]) {

        result = [(UINavigationController *)resulttopViewController];

    }

    return result;

}


19.如何得到UIImage的大小(KB)

            NSData *imageData =UIImageJPEGRepresentation(result,0.5);

            

            float length = [imageDatalength]/1000;


=============================================================================================================
=============================================================================================================


1.Xcode运行出现这个问题:


Please verify that your device’s clock is properly set, and that your signing certificate is not expired. 

这是你的证书失效了。

解决办法

In Xcode, go to Preferences --> Accounts --> View Details,左下有个Download all,重新配置一下就好了


2.couldn’t be completed. (LaunchServicesError error 0.)

解决办法:选择ios模拟器,reset一下。


3.could not launch""process launch failed:Security

解决办法:设置->通用->描述文件与设备管理->开发商应用->信任你所跑的应用

4.

去到/Users/victor/Library/MobileDevice文件下,把你之前的配置文件全删掉,重新添加一遍,OK。

5.

iOS真机调试


解决办法

In Xcode, go to Preferences --> Accounts --> View Details,左下有个Download all,重新配置一下就好了

这边重新下载证书之后,还有错误。下面进一步查看错误是怎么产生的。 
既然证书错误,肯定得看进入”钥匙串访问“管理工具。 
查看了钥匙串——证书,发现了以下问题,截图如下: 
2 
这样子问题就很明朗了。 
这边通过Xcode下载证书,其实是安装了一个新的证书,但是之前的相同的证书没有覆盖掉。 
这边直接将相同的,过期的证书删除。 
然后重新运行项目,就OK了。

总结: 凡是证书问题,多半都是钥匙串里面证书多个重复,而没有覆盖,需要删除之前失效的证书。

6.“(null)” is of a model that is not supported by this version of Xcode. Please use a different device

今天真机运行碰见了这个问题(“(null)” is of a model that is not supported by this version of Xcode. Ple),发现将XCode重启后就可以真机运行了,碰见这个问题的朋友可以试下

7.

问题:第一次运行一个新的设备,没有信任

解决办法,拔掉重新连接,选择信任。

8.


手机系统更新过,需要下载新的包放入Xcode中

步骤如下:
打开Finder
找到应用程序文件夹
在里面找到XCode
点击XCode,右键,显示包内容
Contents-->Developer-->Platforms-->iPhoneOS.platform-->DeviceSupport
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
然后你就能看到你的Xcode支持的真机测试的一些系统型号对应的文件

9. 

iOS中项目运行到真机上提示设备被锁定解决方法Development cannot be enabled while your device is locked.

解决办法:手机升级到iOS 10之后,运行真机出现了Development cannot be enabled while your device is locked.

这里是你对这台电脑设置了不信任;

解决方法是:打开手机设置->通用->还原->还原位置与隐私;

然后会有弹窗提示你是否信任此电脑,点击信任,重启Xcode之后,运行项目到手机上

10.


解决方法: 
1、尝试重新拔插测试设备。 
2、如果“1”不起作用,重启Xcode尝试。 
3、如果“2”不起作用,重启手机,然后尝试。

4.如果前三都不起作用,使用问题5方法。

11.iOS真机调试问题-App installation failed

真机调试免费App ID出现的问题
The maximum number of apps for free development profiles has been reached.
免费应用程序调试最大限度
苹果免费App ID只能运行2个应用程序,当调试第三个的时候就会报这个错误,必须把之前的应用程序删除,才能调试新的 

  • 出现问题

    免费ID最多能装2个应用程序,当出现第三个的时候就会报这个错误
  • 解决问题 

    连接iPhone 打开Xcode->Window->Devices


打开Xcode->Window->Devices
  • 接着出现这个界面

    当前有三个应用程序,包括本次运行的应用程序
  • 删除其中一个,不是本次运行的应用程序

    选中要删除的应用程序,点击 -
  • 接着会弹框

    直接选中Delete
  • 再次运行,大工告成
12.

This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.

从上面的报错信息可以看出,主线程在运行的时候子线程修改了主线程UI的布局约束,在iOS开发中,所有的有关界面UI的更新操作必须奥在主线程中完成。这样的错误很容易出现在使用block的时候,因为block就是在子线程中进行的。
解决的办法就是在刚才写的代码中有关针对UI更新的操作放到主线程中。


==================================================================================================================
==================================================================================================================

iOS 如何关闭所有断点、移除所有断点

Disable Breakpoints 是让你的断点不能用
Delete Breakpoints 是删除所有断点
在项目运行的时候,有时候会莫名其妙有断点,但是显示没有断点,这时候你只要删除所有断点就可以正常运行了

调试bug总有崩溃的地方,这里有一个办法可以使得程序断点出现在你有问题的部分
就是下图第二行 Add Exception Breakpoint...

再来就是条件断点  Add Symbolic Breakpoint...
可以只走某个你规定的方法







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值