本文仅为记录个人适配iOS13的历程
1、第一步先升级所有第三方库 **
先到cd到项目文件夹下,pod setup。
执行完毕对Podfile里的SDK进行挨个search,查看当前最新版本。
pod search xxxx 找到当前最新版本并修改版本号。
确保有可能会受13影响的库都升级到最新之后 pod install。
2、处理升级各SDK之后的报错 **
比如升级AFNetworking到4.0之后,所有请求发送处新加了便于客户配置请求头的header参数,若无特殊配置直接传空字典就是。幸好给发送请求的方法又套了一层,否则得改死我。。。
/**
Creates and runs an `NSURLSessionDataTask` with a `POST` request.
@param URLString The URL string used to create the request URL.
@param parameters The parameters to be encoded according to the client request serializer.
@param headers The headers appended to the default headers for this request.
@param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
@param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
@param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
@see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
*/
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(nullable id)parameters
headers:(nullable NSDictionary <NSString *, NSString *> *)headers
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
再有,有些项目会有用到 Application Extension;比如显示多媒体通知的notification extension。会默认也配置到主项目里边去,此时就会飘红了,需要去主项目的 “Pods-项目名.debug.xcconfig”“Pods-项目名.debug.release”删掉对GTExtensionSDK的配置。
3、运行起来之后,各个页面点点,改掉13下的各种崩溃 **
发现了大概三处崩溃吧,其中两处是之前各文章中都提到过的KVC了私有属性;如:对searchBar修改,UITextField修改placeholdercolor等。
另外一处是notification发通知更改UI的代码没有getmainqueue导致,添加获取主线程之后再进行更新UI,解决。
- (void)updateSendProgres:(NSNotification *)notice{
NSInteger progress = [notice.object[K_SEND_PROGRESS] integerValue];
dispatch_async(dispatch_get_main_queue(), ^{
if (progress >= 100) {
self.maskV.progressL.text = @"1%";
}else{
self.maskV.progressL.text = [[NSString stringWithFormat:@"%ld",progress] stringByAppendingString:@"%"];
}
});
}
11下的xcode编译运行到13以下的设备执行该段代码并无异常,不知道是13后要求更严了还是13后通知的事件响应线程发生了变化。。。
这块有待深入探索
4、modalPresentationStyle 默认值的改变 **
由原来的默认0 改成了UIModalPresentationAutomatic,虽然效果不错,但是13以下的怎么办呢🤣。只好挨处在present之前修改要present的VC的modalPresentationStyle。
另外,UIModalPresentationAutomatic下,该VC的生命周期也将收到影响。
5、UIWebview的废弃 **
对我没啥影响,起项目初就是封装的WKWebView😄。
6、暗黑模式 **
个人感觉就是再配一套icon,动态获取下颜色;具体操作看原本项目里的封装和规范吧。
我的icon基本都在asset里,相对简单,找到对应的imageset修改Appearances为”Any,Dark“放进去就好。
颜色这块儿,我目前项目里就会很尴尬了;设计中极其相似的蓝都非得俩色号、、、最后决定先放弃适配dark mode。
直接配置项目不适配dark,
info.plist里添加键值对User Interface Style 值设置为 Light。也可代码关闭:
if(@available(iOS 13.0,*)){
self.window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}
7、改用LaunchScreen.storyboard **
老项目嘛,肯定删掉了的;如今就是创建个SB,拖个UIImageView,约束一下,视当前项目启动图样式决定图片的填充模式就行了。
值得一提的是记得☑️use as Launch Screen
8、deviceToken的格式 **
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token;
BOOL bSucc;
[[RCIMClient sharedRCIMClient] setDeviceTokenData:deviceToken];
if (@available(iOS 13.0, *)){
bSucc = [GeTuiSdk registerDeviceTokenData:deviceToken];
NSMutableString *deviceTokenString = [NSMutableString string];
const char *bytes = deviceToken.bytes;
NSInteger count = deviceToken.length;
for (int i = 0; i < count; i++) {
[deviceTokenString appendFormat:@"%02x", bytes[i]&0x000000FF];
}
token = [deviceTokenString mutableCopy];
}else{
token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
bSucc = [GeTuiSdk registerDeviceToken:token];
}
当然,各SDK的新版本也已经进行了处理,例如我用到的个推和融云。
提到这俩SDK, 还特么闹了个笑话:
我去质问这两家的技术支持为什么升级之后用以上方法设置了deviceToken之后,所有设备都收不到远程推送了?
搞半天是我的P12过期了、、、
主要是因为最初去apple developer看的证书还一个多月到期,但是不知为何挂人官网的p12早在7天前就过期了。
9、keywindow的获取和状态栏的隐藏 **
@property(nullable, nonatomic,readonly) UIWindow *keyWindow API_DEPRECATED("Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes", ios(2.0, 13.0));
@property(nonatomic,readonly) NSArray<__kindof UIWindow *> *windows;
大体意思就是往日的keywindow属性无法满足多窗口时使用。
13后可以用windows数组取其0元素获取,但是我当前APP不适配pad,我也就暂时没去管它。
大概可以这么干:
#define KEYWINDOW [[UIApplication sharedApplication] keyWindow]
//#if (__IPHONE_13_0)
//#define KEYWINDOW [UIApplication sharedApplication].windows[0]
//#elif (__IPHONE_9_0)
//#define KEYWINDOW [[UIApplication sharedApplication] keyWindow]
//#endif
关于隐藏状态栏,之前我设keywindow的level为最大使其在statusBar之上的办法,在13完全失效。。。
UIWindow *window = [UIApplication sharedApplication].keyWindow;
window.windowLevel = UIWindowLevelStatusBar+10.0f;
由于此处是在一个小工具类里用到,暂时还没想到什么办法可以解决😭。
哪位仁兄解决了view里隐藏状态栏的话,还请不吝赐教!!!
🍻我先干为敬了~~🍺🍺🍺