1 ## 获得自定义的所有相簿
2
3 // 获得所有的自定义相簿
4 PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
5 // 遍历所有的自定义相簿
6 for (PHAssetCollection *assetCollection in assetCollections) {
7
8 }
9
10
11 ## 获得相机胶卷相簿
12
13 // 获得相机胶卷
14 PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
15
16
17 ## 获得某个相簿的缩略图
18
19 PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
20 // 同步获得图片, 只会返回1张图片
21 options.synchronous = YES;
22
23 // 获得某个相簿中的所有PHAsset对象
24 PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
25 for (PHAsset *asset in assets) {
26 CGSize size = CGSizeZero;
27
28 // 从asset中获得图片
29 [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
30 NSLog(@"%@", result);
31 }];
32 }
33
34
35 ## 获得某个相簿的原图
36
37 PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
38 // 同步获得图片, 只会返回1张图片
39 options.synchronous = YES;
40
41 // 获得某个相簿中的所有PHAsset对象
42 PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
43 for (PHAsset *asset in assets) {
44 CGSize size = CGSizeMake(asset.pixelWidth, asset.pixelHeight);
45
46 // 从asset中获得图片
47 [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
48 NSLog(@"%@", result);
49 }];
50 }
51
52
53 ## 利用UIImagePickerController挑选图片
54
55 // UIImagePickerController : 可以从系统自带的App(照片\相机)中获得图片
56
57 // 判断相册是否可以打开
58 if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
59
60 UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
61 // 打开照片应用(显示所有相簿)
62 ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
63 // 打开照片应用(只显示"时刻"这个相簿)
64 // ipc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
65 // 照相机
66 // ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
67 ipc.delegate = self;
68 [self presentViewController:ipc animated:YES completion:nil];
69
70 #pragma mark - <UIImagePickerControllerDelegate>
71 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
72 {
73 // 销毁控制器
74 [picker dismissViewControllerAnimated:YES completion:nil];
75
76 // 设置图片
77 self.imageView.image = info[UIImagePickerControllerOriginalImage];
78 }
79
80
81 ## NaN错误
82 - 错误起因:0被当做除数, 比如 10 / 0
83
84 ## 最简单的方法保存图片到相机胶卷
85
86 UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
87
88 /**
89 * 通过UIImageWriteToSavedPhotosAlbum函数写入图片完毕后就会调用这个方法
90 *
91 * @param image 写入的图片
92 * @param error 错误信息
93 * @param contextInfo UIImageWriteToSavedPhotosAlbum函数的最后一个参数
94 */
95 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
96 {
97 if (error) {
98 [SVProgressHUD showErrorWithStatus:@"图片保存失败!"];
99 } else {
100 [SVProgressHUD showSuccessWithStatus:@"图片保存成功!"];
101 }
102 }
103
104
105 ## 保存图片到自定义相册
106
107 - (IBAction)save {
108 /*
109 PHAuthorizationStatusNotDetermined, 用户还没有做出选择
110 PHAuthorizationStatusDenied, 用户拒绝当前应用访问相册(用户当初点击了"不允许")
111 PHAuthorizationStatusAuthorized 用户允许当前应用访问相册(用户当初点击了"好")
112 PHAuthorizationStatusRestricted, 因为家长控制, 导致应用无法方法相册(跟用户的选择没有关系)
113 */
114
115 // 判断授权状态
116 PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
117 if (status == PHAuthorizationStatusRestricted) { // 因为家长控制, 导致应用无法方法相册(跟用户的选择没有关系)
118 [SVProgressHUD showErrorWithStatus:@"因为系统原因, 无法访问相册"];
119 } else if (status == PHAuthorizationStatusDenied) { // 用户拒绝当前应用访问相册(用户当初点击了"不允许")
120 MKLog(@"提醒用户去[设置-隐私-照片-xxx]打开访问开关");
121 } else if (status == PHAuthorizationStatusAuthorized) { // 用户允许当前应用访问相册(用户当初点击了"好")
122 [self saveImage];
123 } else if (status == PHAuthorizationStatusNotDetermined) { // 用户还没有做出选择
124 // 弹框请求用户授权
125 [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
126 if (status == PHAuthorizationStatusAuthorized) { // 用户点击了好
127 [self saveImage];
128 }
129 }];
130 }
131 }
132
133 - (void)saveImage
134 {
135 // PHAsset : 一个资源, 比如一张图片\一段视频
136 // PHAssetCollection : 一个相簿
137
138 // PHAsset的标识, 利用这个标识可以找到对应的PHAsset对象(图片对象)
139 __block NSString *assetLocalIdentifier = nil;
140
141 // 如果想对"相册"进行修改(增删改), 那么修改代码必须放在[PHPhotoLibrary sharedPhotoLibrary]的performChanges方法的block中
142 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
143 // 1.保存图片A到"相机胶卷"中
144 // 创建图片的请求
145 assetLocalIdentifier = [PHAssetCreationRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier;
146 } completionHandler:^(BOOL success, NSError * _Nullable error) {
147 if (success == NO) {
148 [self showError:@"保存图片失败!"];
149 return;
150 }
151
152 // 2.获得相簿
153 PHAssetCollection *createdAssetCollection = [self createdAssetCollection];
154 if (createdAssetCollection == nil) {
155 [self showError:@"创建相簿失败!"];
156 return;
157 }
158
159 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
160 // 3.添加"相机胶卷"中的图片A到"相簿"D中
161
162 // 获得图片
163 PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetLocalIdentifier] options:nil].lastObject;
164
165 // 添加图片到相簿中的请求
166 PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdAssetCollection];
167
168 // 添加图片到相簿
169 [request addAssets:@[asset]];
170 } completionHandler:^(BOOL success, NSError * _Nullable error) {
171 if (success == NO) {
172 [self showError:@"保存图片失败!"];;
173 } else {
174 [self showSuccess:@"保存图片成功!"];;
175 }
176 }];
177 }];
178 }
179
180 /**
181 * 获得相簿
182 */
183 - (PHAssetCollection *)createdAssetCollection
184 {
185 // 从已存在相簿中查找这个应用对应的相簿
186 PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
187 for (PHAssetCollection *assetCollection in assetCollections) {
188 if ([assetCollection.localizedTitle isEqualToString:XMGAssetCollectionTitle]) {
189 return assetCollection;
190 }
191 }
192
193 // 没有找到对应的相簿, 得创建新的相簿
194
195 // 错误信息
196 NSError *error = nil;
197
198 // PHAssetCollection的标识, 利用这个标识可以找到对应的PHAssetCollection对象(相簿对象)
199 __block NSString *assetCollectionLocalIdentifier = nil;
200 [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
201 // 创建相簿的请求
202 assetCollectionLocalIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:XMGAssetCollectionTitle].placeholderForCreatedAssetCollection.localIdentifier;
203 } error:&error];
204
205 // 如果有错误信息
206 if (error) return nil;
207
208 // 获得刚才创建的相簿
209 return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[assetCollectionLocalIdentifier] options:nil].lastObject;
210 }
211
212 - (void)showSuccess:(NSString *)text
213 {
214 dispatch_async(dispatch_get_main_queue(), ^{
215 [SVProgressHUD showSuccessWithStatus:text];
216 });
217 }
218
219 - (void)showError:(NSString *)text
220 {
221 dispatch_async(dispatch_get_main_queue(), ^{
222 [SVProgressHUD showErrorWithStatus:text];
223 });
224 }
225
226
227 ## Xcode插件的安装路径
228
229 /Users/用户名/Library/Application Support/Developer/Shared/Xcode/Plug-ins