前言
项目说明
《从此生活》项目是我去年开始的项目,一个装饰类的短视频项目,项目中集成了
七牛云
的 SDK。
该篇文章会不定期更新日常版本迭代中项目被拒的日志及其对应的解决办法。
目录
1、v1.1.0(001)
因为 itunesConnect 中屏幕快照非截屏状态而引起被拒问题(此版本的被拒日志忘记记录了,此处只是简单描述一下)
2、1.1.3(001)
Guideline 2.1 - Performance - App Completeness
Your app crashed on iPad running iOS 12.2 on WiFi when we:
tapped the icon of Close after we tapped Plus in the middle.
We have attached detailed crash logs to help troubleshoot this issue.
具体问题描述及解决办法
1、v1.1.0(001)
问题:
因为我们最开始在 itunesConnect 里的屏幕快照中设置的图片是从 UI 那里直接拿取的经过加工的图片,在实际项目中是无法找到对应的界面或类似的界面的,所以才会被拒的。
解决办法:
最简单的方式是直接拿引导页的图片或者直接通过手机或模拟器在 App 运行的过程中截取几张图片即可。
2、v1.1.3(001)
### Guideline 2.1 - Performance - App Completeness
Your app crashed on iPad running iOS 12.2 on WiFi when we:
tapped the icon of Close after we tapped Plus in the middle.
We have attached detailed crash logs to help troubleshoot this issue.
**Next Steps**
To resolve this issue, please revise your app and test it on a device to ensure that it runs as expected.
**Resources**
For information on how to symbolicate and read a crash log, please review [Tech Note TN2151 Understanding and Analyzing Application Crash Reports](https://developer.apple.com/library/archive/technotes/tn2151/_index.html).
Please see attached screenshot for details.
v1.1.3(001)
Crash 日志:
Fatal Exception: NSObjectInaccessibleException(This application is not allowed to access Photo data)
现象:
当刚进入该录制页面,但是 禁止所有权限 或者 禁止单独的相册访问权限,点击该页面的关闭按钮,会引起 crash。
原因:
项目中在跳转到视频录制界面时,会优先进行权限鉴定,鉴权包括
相册的访问权限
、摄像头的访问权限
、麦克风的访问权限
;需求中有在进行相应的初始化及鉴权后,本地上传按钮的缩略图会变更为当前相册中最新视频的缩略图这一需求。
项目中是通过PHCachingImageManager
对象处理获取相册中首个视频的第一帧图片的。PHCachingImageManager
在初始化的时候会添加DISPATCH_SOURCE_TYPE_MEMORYPRESSURE dispatch source event
,当内存不够会尝试移除缓存,且PHCachingImageManager
是个懒加载对象,意味着当回调发生时,会隐式初始化调用-[PHImageManager defaultManager]
,如果没有获取相册权限,则会导致 crash。解决办法:
只需要在调用
[[PHCachingImageManager alloc] init]
初始化之前,先保证已经获取到 相册的访问权限(PHAuthorizationStatusAuthorized - 用户已经授权应用访问照片数据
) 才可以进行初始化。
所以之前需要先进行权限判断,然后再进行初始化,最后再进行获取视频第一帧图片。参考链接:
1、Fatal Exception: NSObjectInaccessibleException(This application is not allowed to access Photo data)
2、iOS相册、相机权限判断及跳转至设置界面
3、iOS关于相机相册权限设置
4、iOS 获取用户是否有(相册/相机)权限
#pragma mark - 获取当前本地所有视频
+ (NSArray *)getAllLocalVide {
// 参考链接:https://www.jianshu.com/p/ea0274a33209、https://www.jianshu.com/p/c345dab953f9
// 获取所有相册合辑【视频相册】
PHFetchResult *videoResults = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumVideos options:nil];
// 获取视频相册
PHAssetCollection *videoCollection = [videoResults firstObject];
// 获取视频相册内容合集
PHFetchResult *videos = [PHAsset fetchAssetsInAssetCollection:videoCollection options:nil];
NSLog(@"相册名:%@,有 %ld 个视频", videoCollection.localizedTitle, videos.count);
NSMutableArray *tempVideos = [NSMutableArray array];
for (PHAsset *videoSet in videos) {
[tempVideos addObject:videoSet];
}
// 逆序
NSArray *allVideo = [[tempVideos reverseObjectEnumerator] allObjects];
return allVideo;
}
#pragma mark - 获取视频第一帧
- (void)getFirstFrameImage {
self.imageManager = [[PHCachingImageManager alloc] init];
// 最新的视频缩略图
PHAsset *asset = [[LHAPI getAllLocalVide] firstObject];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeFast;
// 取出第一帧
[self.imageManager requestImageForAsset:asset targetSize:self.localBtn.frame.size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
[self.localBtn setImage:result forState:UIControlStateNormal];
}];
}
#pragma mark - 跳转应用设置界面
+ (void)goToAppSystemSettingWithAlbumPermissions {
/**
判断是否获取相册访问读写权限,否则不可以初始化 PHCachingImageManager
PHAuthorizationStatusNotDetermined = 0, // 默认还没做出选择
PHAuthorizationStatusRestricted, // 此应用程序没有被授权访问的照片数据
PHAuthorizationStatusDenied, // 用户已经明确否认了这一照片数据的应用程序访问
PHAuthorizationStatusAuthorized // 用户已经授权应用访问照片数据
*/
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status != PHAuthorizationStatusAuthorized) {
UIApplication *application = [UIApplication sharedApplication];
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
dispatch_async(dispatch_get_main_queue(), ^{
if ([application canOpenURL:url]) {
if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[application openURL:url options:@{} completionHandler:nil];
}
}
});
}
}
网友评论