欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS - 开发

程序员文章站 2022-03-23 20:34:32
1. Xcode在真机调试的时候出现”The identity used to sign the executable is no longer valid&rdquo...

1. Xcode在真机调试的时候出现”The identity used to sign the executable is no longer valid”

解决方案:
(1)provisioning Profile文件选择错误
(2)provisioning Profile已失效
(3)开发者证书过期或者被删除了

2. 将storyBoard里的控制器进行实例化

注:需要在Storyboard里面设置控制器的Storyboard ID

//Identifier:@“Storyboard ID”
//将storyBoard实例化 (1)(可以在AppDelegate里面使用)
    UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    //将要跳转控制器通过storyBoard实例化
    ViewController *VC = [mainSB instantiateViewControllerWithIdentifier:@"ViewController"];
    VC.isModifyPassword = NO;
    [self.navigationController pushViewController:VC animated:YES];

//将storyBoard实例化 (2)
//将要跳转控制器通过storyBoard实例化
    ViewController *VC = [self.storyboard  instantiateViewControllerWithIdentifier:@"ViewController"];
    VC.isModifyPassword = NO;
    [self.navigationController pushViewController:VC animated:YES];

3. 仿安卓Toast

#import 
#import 

//声明定义一个ToastLabel对象
@interface ToastLabel : UILabel

- (void)setMessageText:(NSString *)text;

@end

@interface Toast : NSObject
{

    ToastLabel *toastLabel;
    NSTimer *countTimer;
    NSInteger changeCount;
}

//创建声明单例的方法
+ (instancetype)shareInstance;

- (void)makeToast:(NSString *)message duration:(CGFloat )duation;

@end

#import "Toast.h"


@implementation ToastLabel

/**

 * ToastLabel初始化,位label设置各种属性
 *
 * @return ToastLabel

 */

- (instancetype)init{

    self = [super init];
    if (self) {
        self.layer.cornerRadius = 10;
        self.layer.masksToBounds = YES;
        self.backgroundColor = [UIColor blackColor];
        self.numberOfLines = 0;
        self.textAlignment = NSTextAlignmentCenter;
        self.textColor = [UIColor whiteColor];
        self.font = [UIFont systemFontOfSize:15];
    }
    return self;
}

/**
 * 设置显示的文字
 *
 * @aram text 文字文本
 */

- (void)setMessageText:(NSString *)text{
    [self setText:text];

    CGRect rect = [self.text boundingRectWithSize:CGSizeMake(DeviceWidth - 20, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:self.font} context:nil];

    CGFloat width = rect.size.width + 20;
    CGFloat height = rect.size.height + 20;
    CGFloat x = (DeviceWidth - width) / 2;
    CGFloat y = DeviceHight - height - 80;

    self.frame = CGRectMake(x, y, width, height);

}

@end

@implementation Toast

/**
 *  实现声明单例的方法 GCD
 *
 *  @return 单例
 */

+ (instancetype)shareInstance{

    static Toast *singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        singleton = [[Toast alloc] init];

    });

    return singleton;
}

/**
 *  初始化方法
 *
 *  @return 自身
 *
 */

- (instancetype)init{

    self = [super init];
    if (self) {
        toastLabel = [[ToastLabel alloc] init];

        countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeTime) userInfo:nil repeats:YES];
        countTimer.fireDate = [NSDate distantFuture];//关闭定时器
    }

    return self;
}

/**
 *  弹出并显示Tosat
 *
 *  @param message  显示的文本内容
 *  @param duration 显示时间
 */
- (void)makeToast:(NSString *)message duration:(CGFloat)duation{

    if ([message length] == 0) {
        return;
    }
    [toastLabel setMessageText:message];
    [[[UIApplication sharedApplication]keyWindow ] addSubview:toastLabel];

    toastLabel.alpha = 0.8;
    countTimer.fireDate = [NSDate distantPast];//开启定时器
    changeCount = duation;
}

/**
 *   定时器回调方法
 */

- (void)changeTime{

    //NSLog(@"时间:%ld",changeCount);
    if (changeCount-- <= 0) {
        countTimer.fireDate = [NSDate distantFuture];//关闭定时器
        [UIView animateWithDuration:0.2f animations:^{
            toastLabel.alpha = 0;
        } completion:^(BOOL finished) {
            [toastLabel removeFromSuperview];
        }];
    }
}

@end

//duration:显示的时长
[[Toast shareInstance] makeToast:@"你提示的内容" duration:1.0];

4. UITextField的左视图设置

//1.创建UITextField类别

#import 

@interface loginUITextField : UITextField

@end

//2.重写UITextField的左视图的Bounds
#import "loginUITextField.h"

@implementation loginUITextField

- (CGRect)leftViewRectForBounds:(CGRect)bounds

{
    CGRect rect = [super leftViewRectForBounds:bounds];

    if (self.window.frame.size.width == 320) {

        rect = CGRectMake(rect.origin.x + 3, rect.origin.y , 28, 28);

    } else if (self.window.frame.size.width == 375){

        rect = CGRectMake(rect.origin.x + 4, rect.origin.y , 32, 32);

    } else {

        rect = CGRectMake(rect.origin.x + 5, rect.origin.y , 35, 35);
    }

    return rect;
}

@end

//以下是例子  并不能直接使用
//_userTextField的左视图
    UIImageView *useImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"user"]];
    _userImageView.contentMode = UIViewContentModeScaleAspectFit;
    _userTextField.leftView = useImageView;
    _userTextField.leftViewMode = UITextFieldViewModeAlways;
    _userTextField.borderStyle = UITextBorderStyleRoundedRect;

    //修改水印字体颜色和字体大小
    [_userTextField setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
    [_userTextField setValue:[UIFont boldSystemFontOfSize:15] forKeyPath:@"_placeholderLabel.font"];


    //_passwordTxetField的左视图
    UIImageView *passwdImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"locked"]];
    //passwdImageView.frame = CGRectMake(0, 0, 37, 37);
    _passwordTxetField.contentMode = UIViewContentModeScaleAspectFit;
    _passwordTxetField.leftView = passwdImageView;
    _passwordTxetField.leftViewMode = UITextFieldViewModeAlways;
    _passwordTxetField.borderStyle = UITextBorderStyleRoundedRect;

    //修改水印字体颜色和字体大小
    [_passwordTxetField setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
    [_passwordTxetField setValue:[UIFont boldSystemFontOfSize:15] forKeyPath:@"_placeholderLabel.font"];

5. 自定义NavgationBar的标题和返回按钮无文字的样式和设置NavgationBar的背景图

//自定义NavgationBar的标题
- (void)creatdTitle{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 45)];
    label.text = @"标题";
    label.font = [UIFont boldSystemFontOfSize:20];
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    self.navigationItem.titleView = label;
}

//返回按钮无文字的样式
- (void)createdbackBarButtonItem{
    UIBarButtonItem *newBarButtonItem = [[UIBarButtonItem alloc] init];
    newBarButtonItem.title = @"";
    self.navigationItem.backBarButtonItem = newBarButtonItem;
    [self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
}

//设置NavgationBar的背景图 (jpg记得加后缀)
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"1"] forBarMetrics:UIBarMetricsDefault];

6. 自定义UIAlertController的标题、内容、和按钮的字体样式

- (void)created{

    NSString *str = @"注  销";

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:str preferredStyle:UIAlertControllerStyleAlert];

    NSMutableAttributedString *alertControllerStr = [[NSMutableAttributedString alloc] initWithString:str];

    [alertControllerStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, str.length)];
    [alertControllerStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:25] range:NSMakeRange(0, str.length)];

        [alertController setValue:alertControllerStr forKey:@"attributedMessage"];

    UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {



    }];

    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

    }];
    [cancelAction setValue:[UIColor grayColor] forKey:@"titleTextColor"]; 

    [alertController addAction:confirmAction];
    [alertController addAction:cancelAction];

    [self presentViewController:alertController animated:YES completion:nil];

}
//self.verificationBtn:改成你自己的命名的button

- (void)startTime{
    __block int timeout = 59; //倒计时时间
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
    dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行

    dispatch_source_set_event_handler(_timer, ^{
        if(timeout<=0){ //倒计时结束,关闭
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //设置界面的按钮显示 根据自己需求设置(倒计时结束后调用)
                [self.verificationBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
                [self.verificationBtn setBackgroundColor:[UIColor colorWithRed: 0/256.0 green: 111/256.0 blue: 255/256.0 alpha:1]];

                //设置可点击
                self.verificationBtn.userInteractionEnabled = YES;

            });
        }else{
            // int minutes = timeout / 60;    //这里注释掉了,这个是用来测试多于60秒时计算分钟的。
            int seconds = timeout % 60;
            NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds];
            dispatch_async(dispatch_get_main_queue(), ^{
                //设置界面的按钮显示 根据自己需求设置
                //NSLog(@"____%@",strTime);
                [UIView beginAnimations:nil context:nil];
                [UIView setAnimationDuration:1];

                [self.verificationBtn setTitle:[NSString stringWithFormat:@"%@秒重新发送",strTime] forState:UIControlStateNormal];
                [UIView commitAnimations];
                self.verificationBtn.backgroundColor = [UIColor lightGrayColor];
                //设置不可点击
                self.verificationBtn.userInteractionEnabled = NO;

            });

            timeout--;
        }
    });

    dispatch_resume(_timer);

}

8. 各种切圆角(基本上能切得都这样切)

    //头像图片切圆
    _userImageView.layer.cornerRadius = _userImageView.frame.size.width / 2;
    _userImageView.layer.masksToBounds = YES;

    //
    _textFiled.layer.cornerRadius = 10;
    _textFiled.layer.masksToBounds = YES;

    //
    view.layer.cornerRadius = 20;
    view.layer.masksToBounds = YES;

9.避免程序因为NSNull而导致奔溃

//创建个类别
#import 

@interface NSNull (IsNull)

@end

#import "NSNull+IsNull.h"

@implementation NSNull (IsNull)

- (void)forwardInvocation:(NSInvocation *)invocation

{

    if ([self respondsToSelector:[invocation selector]]) {

        [invocation invokeWithTarget:self];

    }

}


- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector

{

    NSMethodSignature *sig = [[NSNull class] instanceMethodSignatureForSelector:selector];

    if(sig == nil) {

        sig = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];

    }

    return sig;

}

@end

10.AFNetworking的一个小问题(获取数据的类型不对时,进行更改)

    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/plain",@"text/html",@"image/jpg",nil];

11.极光推送程序内的代码

//1.创建一个类

#import 
#import 


@interface CFPushHelper : NSObject



///----------------------------------------------------
/// @name Setup 启动相关
///----------------------------------------------------
+ (NSString *)registrationID;
/*!
 * @abstract 启动SDK
 *
 * @param launchingOption 启动参数.
 * @param appKey 一个JPush 应用必须的,唯一的标识. 请参考 JPush 相关说明文档来获取这个标识.
 * @param channel 发布渠道. 可选.
 * @param isProduction 是否生产环境. 如果为开发状态,设置为 NO; 如果为生产状态,应改为 YES.
 * @param advertisingIdentifier 广告标识符(IDFA) 如果不需要使用IDFA,传nil.
 *
 * @discussion 提供SDK启动必须的参数, 来启动 SDK.
 * 此接口必须在 App 启动时调用, 否则 JPush SDK 将无法正常工作.
 */
+ (void)setupWithOption:(NSDictionary *)launchingOption
                 appKey:(NSString *)appKey
                channel:(NSString *)channel
       apsForProduction:(BOOL)isProduction
  advertisingIdentifier:(NSString *)advertisingId;

///----------------------------------------------------
/// @name APNs about 通知相关
///----------------------------------------------------

/*!
 * @abstract 注册要处理的远程通知类型
 *
 * @param types 通知类型
 * @param categories
 *
 * @discussion
 */
//+ (void)registerForRemoteNotificationTypes:(NSUInteger)types
//                                categories:(NSSet *)categories;

//上传deviceToken
+ (void)registerDeviceToken:(NSData *)deviceToken;


/*!
 * @abstract 处理收到的 APNs 消息
 */
//+ (void)handleRemoteNotification:(NSDictionary *)userInfo;


// ios7以后,才有completion,否则传nil
+ (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion;

/*!
 * @abstract 前台展示本地推送
 *
 * @param notification 本地推送对象
 * @param notificationKey 需要前台显示的本地推送通知的标示符
 *
 * @discussion 默认App在前台运行时不会进行弹窗,在程序接收通知调用此接口可实现指定的推送弹窗。
 */
+ (void)showLocalNotificationAtFront:(UILocalNotification *)notification identifierKey:(NSString *)notificationKey;

@end

//导入极光推送头文件@"JPUSHService.h"

#import "CFPushHelper.h"
#import "JPUSHService.h"

@implementation CFPushHelper

+ (NSString *)registrationID{

   return [JPUSHService registrationID];

}

+ (void)setupWithOption:(NSDictionary *)launchingOption appKey:(NSString *)appKey channel:(NSString *)channel apsForProduction:(BOOL)isProduction advertisingIdentifier:(NSString *)advertisingId{

    //Required
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        //可以添加自定义categories
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound |
                                                          UIUserNotificationTypeAlert)
                                              categories:nil];
    } else {
        //categories 必须为nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                          UIRemoteNotificationTypeSound |
                                                          UIRemoteNotificationTypeAlert)
                                              categories:nil];
    }
    //Required
    // 如需继续使用pushConfig.plist文件声明appKey等配置内容,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化。
    [JPUSHService setupWithOption:launchingOption appKey:appKey
                          channel:channel
                 apsForProduction:isProduction
            advertisingIdentifier:advertisingId];

    return;

}

+ (void)registerDeviceToken:(NSData *)deviceToken{

    [JPUSHService registerDeviceToken:deviceToken];

    return;
}

//+ (void)handleRemoteNotification:(NSDictionary *)userInfo{
//    
//    [CFPushHelper handleRemoteNotification:userInfo];
//    
//}

+ (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion{

    [JPUSHService handleRemoteNotification:userInfo];

    if (completion) {

        completion(UIBackgroundFetchResultNewData);
    }
    return;

}

+ (void)showLocalNotificationAtFront:(UILocalNotification *)notification
                       identifierKey:(NSString *)notificationKey{

    [CFPushHelper showLocalNotificationAtFront:notification identifierKey:nil];

    return;
}


@end

//我这里创建的AppDelegate的类别

#import "AppDelegate.h"

@interface AppDelegate (CFPushSDK)

- (void)JPushapplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

@end


#import "AppDelegate+CFPushSDK.h"
#import "JPUSHService.h"
#import "CFPushHelper.h"

#define JPushSDK_AppKey @"顾名思义"
#define isProduction    NO

@implementation AppDelegate (CFPushSDK)

- (void)JPushapplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

    [CFPushHelper setupWithOption:launchOptions appKey:JPushSDK_AppKey channel:nil apsForProduction:isProduction advertisingIdentifier:nil];

    //注册
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidLoginNotification object:nil];

}

//通知方法
- (void)networkDidReceiveMessage:(NSNotification *)notification {

    //调用接口
    NSLog(@"\n\n极光推送注册成功\n\n");

    //通知后台registrationID
    //NSLog(@"registrationID2 = %@",[CFPushHelper registrationID]);
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![CFPushHelper registrationID]) {

        NSString *registrationID = @"123";
        [defaults setObject:registrationID forKey:@"registrationID"];

    } else {

        [defaults setObject:[CFPushHelper registrationID] forKey:@"registrationID"];

    }
    [defaults synchronize];
    //[CFPushHelper registrationID]
    //注销通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kJPFNetworkDidLoginNotification object:nil];

}

- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    /// Required - 注册 DeviceToken
    //NSLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]);
    [CFPushHelper registerDeviceToken:deviceToken];

}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    // IOS 7 Support Required
    [CFPushHelper handleRemoteNotification:userInfo completion:completionHandler];

    // 应用正处理前台状态下,不会收到推送消息,因此在此处需要额外处理一下
    if (application.applicationState == UIApplicationStateActive) {
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle:@"收到推送消息"
                              message:userInfo[@"aps"][@"alert"]
                              delegate:nil
                              cancelButtonTitle:@"取消"
                              otherButtonTitles:@"确定",nil];
        [alert show];
    }  

    //[self gotoViewControllerWith:userInfo];
    [self gotoViewController];


}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{

    //NSLog(@"did Fail To Register For Remote Notifications With Error : %@",error);

    return;
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{

    [CFPushHelper showLocalNotificationAtFront:notification identifierKey:nil];

    return;
}

- (void)applicationDidBecomeActive:(UIApplication *)application{

    [application setApplicationIconBadgeNumber:0];
    [application cancelAllLocalNotifications];

    return;
}

@end

#import "AppDelegate.h"
#import "JPUSHService.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    //注册极光推送
    [self JPushapplication:application didFinishLaunchingWithOptions:launchOptions];

  return YES;

}

暂时就这样