2017-10-09 21:02:17 Yj_sail 阅读数 7059

iOS11 系统更新后,私有API iOS 11 LSApplicationWorkspace无法获取应用安装列表,导致无法判断某个APP是否已安装。

解决方案:

使用私有库 MobileContainerManager.framework

//iOS 11 判断APP是否安装
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 11.0) {
        NSBundle *container = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
        if ([container load]) {
            Class appContainer = NSClassFromString(@"MCMAppContainer");

            id test = [appContainer performSelector:@selector(containerWithIdentifier:error:) withObject:bundleId withObject:nil];
            NSLog(@"%@",test);
            if (test) {
                return YES;
            } else {
                return NO;
            }
        }
        return NO;

    } else {
           //非iOS11通过获取安装列表判断即可
    }

备注:
适用“积分墙应用”思路:从服务器获取所有的任务,循环任务数据源,若已安装,则不显示,未安装则显示。

2018-01-08 13:36:17 DreamcoffeeZS 阅读数 1694

今天接受了一个改造旧项目的任务,据说项目唯独在iOS11上无法运行。这很容易就让我们想到与最近苹果iOS11放弃支持32位应用的事件有关。确实我在平时开发的项目中也没怎么涉及这个问题,这次在升级应用支持64位的过程中还是遇到了些问题,所以在这里总结一下,也许还会有同行的朋友遇到。

一、iOS11停止支持32位的来由

苹果于2013年9月推出了iPhone 5S新手机,采用的全新A7处理器其最大特色就是支持64位运算。64位A7处理器的使用意味着iPhone性能会大有提高,性能和速度更加出色;而要到达到这样的性能,开发者就要开发64位的应用了。因为即使64位的处理器再出色,如果还是安装32位的应用,那么64位处理的性能也不能发挥出来。

2018年1月1日开始,苹果在iOS 11系统上停止了32位应用程序的服务支持,使用iOS11系统的用户将无法再在Appstore中搜索到32位应用。同时32位的应用不顺应趋势也会停止继续开发,所以iPhone5s以下的机型也都面临着App停止更新的情况,因为从iPhone5s之后的iOS设备才是64位设备,而iPhone5以下都是32位设备,。

二、了解iOS的CPU架构

我们说到了32位和64位的处理器,它们本质的区别还是在于,64位多出2个寄存器,而这两个寄存器在运行32位应用的时候是关闭的,只有在运行64位应用的时候才会激活,才会用上。

这个区别对我们开发产生的影响在于,如果我们在项目中设置了支持不同的CPU架构,那么我们使用的静态库,动态库、以及打包的大小都会受到影响。关于在Xcode中设置不同CPU架构的支持可以参考下另一篇文章:(https://www.jianshu.com/p/441caa1138af)

三、升级32位应用支持64位

其实升级应用支持64位并不复杂,主要有以下两个步骤:

1.修改ARchitectures,设置项目支持64位CPU

我们在Xcode中选择将要设置的target,然后打开build setting, 可以看到有关指令集设置的Architectures选项。
修改Vaild Architectures选项,增加arm64支持。

屏幕快照 2018-01-05 下午7.17.44.png

2.更换各个平台的SDK

在经过上面的修改之后,我们的应用会编译失败。因为我们设置了项目需要支持arm64的架构,但是代码中使用的各个平台的SDK静态库还是只支持32位的。这就需要我们耐心的一个个更换了。这里有三个问题可能我们会遇到:

  1. Xcode提示Build failed,但是没有明显的报错
    解决:打开Xcode左侧导航栏选择最后一项,我们会在这里看到编译错误。

  2. 编译报错Undefined symbols for architecture x86_64
    解决:这就是我们不支持64位的sdk报的错,我们可以从这里找到它并将其更换

  3. 问题三:如何判断一个SDK静态库是否支持64位?
    解决:我们找到这个静态库文件(如百度分析的静态库),使用命令行:lipo -info libBaiduMobStat.a ,我们就可以看到其所支持的类型

四、其他可能遇到的问题

1.XIB报错:compiling IB documents for earlier than ios 7 is no longer supported
我们修改的这类项目通常也是比较旧的代码了,如果使用最新的Xcode打开我们可能会遇到上面的报错。我们可以进行如下的设置来修改这个错误。如果我们在Target->Deployment info ->Deployment Target 设置的是8.0的话,我们对于每个XIB文件也要做如下的修改:
屏幕快照 2018-01-05 下午7.45.49.png

2016-11-14 10:52:14 yihaoxue 阅读数 68

由于天朝的网络环境,在macOS中安装体积较大的软件,都会遭遇一些让人崩溃的问题,比如无法下载或者下载到快完成时,断开了网络连接……在Xcode中也一样,下面介绍下如何获取模拟器下载链接和安装模拟器,也适用于获取其它链接。

环境:Xcode8.0, OS X10.11.6

启动Xcode与控制台,在Xcode-Componets-Simulators中可以看到所有可下载的模拟器。



 

已安装的有iOS8.4与iOS9.3模拟器,点击iOS9.2,会要求验证,开始显示进度条后,点击取消下载,然后看看控制台输出。



 

 

模拟器下载地址为

https://devimages.apple.com.edgekey.net/downloads/xcode/simulators/com.apple.pkg.iPhoneSimulatorSDK9_2-9.2.1.1451951473.dmg

建议使用VPS下载后再转存到本地,因为网络环境实在太差了……

下载后获得文件

com.apple.pkg.iPhoneSimulatorSDK9_2-9.2.1.1451951473.dmg

记住不要修改名字,而且直接安装也是没用的,在Xcode中无法显示。

~/Library/Caches/com.apple.dt.Xcode目录下新建文件夹Downloads,将刚才下载的文件复制到这个目录下,现在它的目录地址是

~/Library/Caches/com.apple.dt.Xcode/Downloads/com.apple.pkg.iPhoneSimulatorSDK9_2-9.2.1.1451951473.dmg

然后在Xcode-Componets-Simulators中再次点击下载iOS9.2模拟器,就能继续安装了,安装完成后是不会删除dmg文件的,如果硬盘空间比较紧凑,还是手动删除吧。

2019-12-24 11:38:33 weixin_45946134 阅读数 91

(1)通用链接在 iOS 11.2+ 中,偶尔会出现失效,无法唤醒拉起 app,为什么?
这是因为苹果 iOS 11.2+ 出现的系统 bug 导致的(偶然发生的),解决方法“删除 app,重启设备,重新安装 app”,苹果目前还没有完全解决这个问题,我们将持续跟进。

(2)微信中为什么不能唤醒,通用链接(Universal Links)被禁用了?
微信在 6.6.1 版本后,禁止了 UniversalLinks 的使用,将提示右上角打开 Safari 来拉起 app,其它 app 和浏览器不受影响。

(3)什么情况 safari 浏览器出现“打不开该网页,因为网页无效”?
这是因为 safari 在通过 scheme 执行跳转时,如果 app 不存在,系统就会出现这样的提示。

(4)重签名的安装包,如果无法正常使用通用链接来唤醒怎么办?
重签包是无法正常使用通用链接来唤醒 app 的,重签包需要配置 scheme 来唤醒 app。

(5)iOS 无法获取自定义参数?
首先检查是否按照官方文档正常集成相关的代码; 是否将集成好的 ipa 包上传到官网平台; 检查是否是覆盖安装或者隔天安装,需卸载 app 安装且 h5 传参是有时效性的。

(6)iOS 下载包时,appstore 地址和集成下载地址哪个地址优先级最高?
不填写任何地址就会下载上传到平台的包,填写 appstore 地址就会跳转 appstore 去下载,填写集成下载地址,就跳转这个地址下载包,优先级最高。

(7)为什么会提示当前 iOS 平台的集成工作尚未完成,请登录 Shareinstall 官网查看详情?
检查是否已经上传 IPA 包到我们平台,且已经上传 10 分钟(上传 10 分钟后生效)。 检查 h5 落地页是否拼接了自定义参数。

(8)为什么上传了 ipa 包,提示不能安装或者此时无法安装?
如果打的 ipa 包是非企业包,需要开发把设备的 UDID 加入到苹果开发者中心,重新生成证书的描述文件,上传更新 ipa 包。

2017-09-13 13:55:05 dangyalingengjia 阅读数 17773

XCode9和iOS11 beta了不知多少版本了,正式版本还没有正式发布。我也终于忍不了了,还是都做了升级。设备版本分别为:
XCode:Version 9.0 beta 6 (9M214v) 10月13日更新GM版
iPhone:11.0(15A5370a)

下面的问题都是在iOS11之前的版本运行完好,但是升级后出现的问题:
1,定位相关
问题描述:无法定位,而且程序在安装后第一次访问定位权限时,无定位权限提示对话框弹出。
原因:iOS11 定位相关的权限做了更改,在iOS11上使用了新的定位权限key。
解决方案:
如果原来申请的权限是始终允许NSLocationAlwaysUsageDescription,那么需要在保留原来的key的基础上增加NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUsageDescription。具体参考另篇博客:
http://blog.csdn.net/dangyalingengjia/article/details/77965029

2,系统相册相关
问题描述:iOS11上读写相册的照片时发生崩溃。
原因:由于相册相关权限的key发生了变化。用户在没有权限的情况下,访问相册导致崩溃。
解决方案:
iOS11之前相册对应的key是NSPhotoLibraryUsageDescription,iOS11对应的Key是NSPhotoLibraryAddUsageDescription。同定位的Key一样,由于key没有兼容性,所以需要保留原key以兼容iOS10及之前版本。

3,关于UIScrollView初始位置变化的问题
由于iOS11废弃了UIViewController的automaticallyAdjustsScrollViewInsets属性,位置需要手动调整。
iOS11中为UIScrollView新增了contentInsetAdjustmentBehavior属性,结合UIAppearance协议,可以统一在appDelegate的didFinishLaunchingWithOptions的最开始增加:

if #available(iOS 11.0, *) {
    UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
}
调整前 调整后
这里写图片描述 这里写图片描述

2017/10/21更新
注意1,如果你需要做一个嵌套WebView的画面,直接将WebView加到self.view中时,那就需要对WebView的ScrollView进行单独处理:

UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic

注意2,对于系统的相册选择视图UIImagePickerController,需要单独处理:

再打开系统相册前设定:
UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic
从相册返回后设定:
UIScrollView.appearance().contentInsetAdjustmentBehavior = .never

4,第三方库WKWebViewJavascriptBridge
问题描述:在WKWebView的回调函数中崩溃:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
原因:WKWebViewJavascriptBridge内部逻辑问题
解决方案:WKWebViewJavascriptBridge最新的6.0.2上仍然没有解决这个问题,可以参考github issue#272
只能手动修改源文件,将WKWebViewJavascriptBridge.m 的L153的if改为 else if
修改后:                        修改前:
WKWebView

5,第三方库CryptoSwift
如果你使用了加解密相关的第三方库CryptoSwift,而且其版本号在0.7.0以下,可能会遇到找不到UInt8等错误。
你需要更新至0.7.0才能支持XCode9中的Swif3.2。可以查看Github上的CryptoSwift的版本介绍:
CryptoSwift版本
将podfile修改为如下,即可编译通过。
pod ‘CryptoSwift’, ‘~> 0.7.0’

6,第三方库GzipSwift
如果你使用了GZip压缩库GZipSwift的话,可能会遇到这样的错误:
Redefinition of module ‘zlib’
Could not build Objective-C module ‘Gzip’
修改podfile为:
pod ‘GzipSwift’, :git => ‘https://github.com/1024jp/GzipSwift.git‘, :branch => ‘swift4’

7,UIVisualEffectView相关的崩溃
iOS11之前可以将UIView直接加到(addSubview)UIVisualEffectView上面,但是在iOS11上面这么做会导致crash。
正确的姿势是:将UIViewaddSubview到UIVisualEffectView的contentView上。

8,关于上传商店相关改变
之前没有1024*1024的icon,同样可以提交商店审核,但是现在不行了。你会在用Application Loader上传完成后收到一个warning,但是在提交审核(包括beta测试版本)时被告知不允许提交。
上传被拒
而且注意,这个1024的图片一定要去掉alpha通道。可以在github上搜索Alpha-Channel-Remover,用这个工具去掉alpha通道。

9,xcodebuild命令的变化
xocdebuild error
之前用的打包命令是:

./xcodebuild_safe.sh -exportArchive -archivePath "${archive_path}" -exportPath "${export_dir}" -exportOptionsPlist "${plist_file}" || Failed "export fail"
cd "${origin_dir}"

在plist中加入就可以了

    <key>provisioningProfiles</key>
    <dict>
        <key>xxx:YourBundleID</key>
        <string>xxx:YourProvisioningProfileName</string>
    </dict>

在XCode9中,xcodebuild命令的-exportOptionsPlist需要增加provisioningProfiles,用来明确指明用到的provisioningprofile。-exportOptionsPlist这个参数只用在手动管理签名的情况下,尝试使用苹果推荐的xcode自动xcode的自动管理。但是发现带有通配符的AppleID还需要为其指定各种权限,遂作罢。还是手动管理签名吧。

10,iPhoneX的适配
问题1:直接模拟器运行是下图这样的,可以看到顶部,底部都有空余区域:
iPhoneX适配前
解决方案:增加iPhoneX用的启动图(1125*2436)可以让画面充满屏幕。
问题2:充满屏幕后,由于iPhoneX的状态条已经不是20pt,而是44pt。我们的工程用的autolayout,自定义的导航条,约束的写法是相对于self.view做64的位移。这样就会出现视图内容跟导航条重叠。
解决方案1:取消原来的状态条20,导航条44等硬编码写法,定义常量。

// 状态条的高度
func statusBarHeight() -> CGFloat {
    var height: CGFloat = 0
    if #available(iOS 11.0, *) {
        // iPhoneX
        if abs(UIScreen.main.bounds.size.height - CGFloat(812)) < CGFloat.leastNormalMagnitude {
            height = 44
        } else {
            height = 20
        }
    } else {
        height = 20
    }
    return height
}
// 导航条高度
let kNavigationBarHeight: CGFloat = 44
// 画面中视图的起始位置
let kViewTopOffset = statusBarHeight() + kNavigationBarHeight

视图的top从kViewTopOffset开始。
解决方案2:使用safeAreaLayoutGuide。它是当前视图安全区域的范围,可以将其看做一个视图。我们做约束的时候,相对于safeAreaLayoutGuide就好了。但是需要在做约束时区分系统版本,代码量大。

总而言之,上面两种做法,都需要巨大的搬砖量。我选择了第一种做法,昨天从下午搬砖到凌晨1点,每个画面都改了一个遍。
参考:
https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/
https://developer.apple.com/videos/play/fall2017/201/
https://developer.apple.com/videos/play/fall2017/801?time=209
http://www.jianshu.com/p/1432a94ef66f

改完后的效果:

图1 图2
修正后1 修正后2
没有更多推荐了,返回首页