提一个很人性化的需求:

在自己的app里使用PC里的图片。

关键点:传输。怎么把图片从PC导入自己的APP。

因为iOS的封闭性,一般用户不能很方便把图片导入手机相册。笔者稍微想了下,实现功能其实也有不少办法。

就一般用户而言,可以通过第三方app中转一下,比如某Q,传到手机,再保存到相册,再从相册中导入。

针对开发自己的app,也有通过上传到服务器中转,ftp直连等等。都可以实现,从中,笔者选择自以为最简单的方式进行了实现。

流程大概如下:

1、通过iTunes将图片上传到app的document里

2、遍历document文件,将图片保存至相册后清除沙盒图片

3、使用系统UIImagePickerController读取图片。

解释一下,虽然可以直接读取document图片,但是那样得自己画界面,麻烦。加载到系统相册,然后甚至可以专门自定义一个图片目录。一目了然,而且对于用户来说,使用自己添加的图片和使用系统相册图片一样,没有学习成本。


主要步骤:

1、通过iTunes将图片上传到app的document里:

要让自己的app可以使用iTunes添加图片,需要在-info.plist里添加配置

Application supports iTunes file sharing -> YES

然后打开iTunes,找到设备,在应用程序的文件共享里可以找到自己的app,右下角添加图片。

2、遍历document文件,将图片保存至相册后清除沙盒图片

iTunes里添加的文件的路径其实就是放在app沙盒的document目录。明确了这一点。我们就可以把文件便利出来了。

NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSFileManager *fileManager = [NSFileManager defaultManager];
//注意:
//这个会遍历出文件夹的子目录
NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:filePath];
//这个只会在根目录遍历文件
NSArray *dirContents = [fileManager contentsOfDirectoryAtPath:filePath error:nil];

把图片保存到相册的方法是

void UIImageWriteToSavedPhotosAlbum (
UIImage *image,
id completionTarget,
SEL completionSelector,
void *contextInfo
);

你可以直接

UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);

一般来说没问题,但图片多了可能会出现丢失的现象,所以我借鉴大家的做法做一个优化

-(void) saveNext{
if (listOfImages.count > 0) {
UIImage *image = [listOfImages objectAtIndex:0];
UIImageWriteToSavedPhotosAlbum(image, self, @selector(savedPhotoImage:didFinishSavingWithError:contextInfo:), nil);
}
else {
[self allDone];
}
} -(void) savedPhotoImage:(UIImage*)image didFinishSavingWithError: (NSError *)error contextInfo: (void *)contextInfo {
if (error) {
//NSLog(@"%@", error.localizedDescription);
}
else {
[listOfImages removeObjectAtIndex:0];
}
[self saveNext];
}

优化的原理是进行了一个递归,确保一次完成再进行下一次。

这样,document下的图片便都保存至了系统的相册。但是我觉得还不够,我希望能够将自己从iTunes里添加的图片,专门放在一个目录下,方便查阅。于是,就上面的方法,我再次进行了一点改造。

这一次,我们使用到了AssetsLibrary。

-(void)saveImage:(UIImage*)image toAlbum:(NSString*)albumName withCompletionBlock:(SaveImageCompletion)completionBlock
{
//write the image data to the assets library (camera roll)
[self writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation
completionBlock:^(NSURL* assetURL, NSError* error) {
//error handling
if (error!=nil) {
completionBlock(error);
return;
}
//add the asset to the custom photo album
[self addAssetURL: assetURL
toAlbum:albumName
withCompletionBlock:completionBlock];
}];
} -(void)addAssetURL:(NSURL*)assetURL toAlbum:(NSString*)albumName withCompletionBlock:(SaveImageCompletion)completionBlock
{
__block BOOL albumWasFound = NO;
//search all photo albums in the library
[self enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
//compare the names of the albums
if ([albumName compare: [group valueForProperty:ALAssetsGroupPropertyName]]==NSOrderedSame) {
//target album is found
albumWasFound = YES;
//get a hold of the photo's asset instance
[self assetForURL: assetURL
resultBlock:^(ALAsset *asset) {
//add photo to the target album
[group addAsset: asset];
//run the completion block
completionBlock(nil);
} failureBlock: completionBlock];
//album was found, bail out of the method
return;
}
if (group==nil && albumWasFound==NO) {
//photo albums are over, target album does not exist, thus create it
__weak ALAssetsLibrary* weakSelf = self;
//create new assets album
[self addAssetsGroupAlbumWithName:albumName
resultBlock:^(ALAssetsGroup *group) {
//get the photo's instance
[weakSelf assetForURL: assetURL
resultBlock:^(ALAsset *asset) {
//add photo to the newly created album
[group addAsset: asset];
//call the completion block
completionBlock(nil);
} failureBlock: completionBlock];
} failureBlock: completionBlock];
//should be the last iteration anyway, but just in case
return;
}
} failureBlock: completionBlock];
}

AssetsLibrary笔者写文时了解不深,能实现功能,其他不深入讨论。

使用:

[self.library saveImage:image toAlbum:@"File Share" withCompletionBlock:^(NSError *error) {
if (error!=nil) {
NSLog(@"Big error: %@", [error description]);
}
[listOfImages removeObjectAtIndex:0];
[self saveNext];
}];

3、使用系统UIImagePickerController读取图片。这个也不多说,固定套路。

- (void)getImagePicker:(NSUInteger)sourceType {

    UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];

    imagePickerController.delegate = self;

    imagePickerController.allowsEditing = YES;

    imagePickerController.sourceType = sourceType;

    [self presentViewController:imagePickerController animated:YES completion:^{}];
} #pragma mark - image picker delegte
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{}]; NSLog(@"did");
} - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:^{}];
NSLog(@"didn't");
}

使用

[self getImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];

最终效果


PS:其实真是简单实现,写了很多其实是自己的分析过程。实现功能几十行代码就能搞定。

另外,之所以iTunes里上传了四张图片而最终只有三张,不是图片丢失,而是我判断图片文件的时候通过后缀,并且抛弃了gif。也不知道有没有更好的方法。

我想过直接把遍历的所有文件全部转成Image,然后通过!(image)来判断。但感觉会很费内存。恕笔者无知。欢迎大神斧正。

附上demo。 http://pan.baidu.com/s/1hqHXBE0 真尴尬,CSDN上传不上去,大家凑合这用吧

简单实现app使用PC图片的更多相关文章

  1. 如何做个简单安卓App流程

    有同学做毕业设计,问怎样做个简单安卓App流程,我是做服务端的,也算是经常接触app,想着做app应该很简单吧,不就做个页面,会跳转,有数据不就行了,我解释了半天,人家始终没听懂,算了,我第二天问了下 ...

  2. 一个先进的App框架:使用Ionic创建一个简单的APP

    原文  http://www.w3cplus.com/mobile/building-simple-app-using-ionic-advanced-html5-mobile-app-framewor ...

  3. Android Studio 制作简单的App欢迎页面——基于Android 6.0

    在许多的Android App中,我们点击进入时,都可以看到一个欢迎页面,大概持续了几秒,然后跳转至主页面.以下是我开发过程中总结出的一些方法和例子. 一.创建一个新的Activity 首先,新建了一 ...

  4. 用PS制作APP的界面图片

    今天就教大家怎么做出这种厚度的地方还不是白色的,而是根据界面内容交相呼应的图案的APP界面展示图片. 以苹果5S的尺寸为例. 步骤: 1.新建一个画布尺寸为:640*1136,然后保存,命名如:5S效 ...

  5. Echo.js – 简单易用的 JavaScript 图片延迟加载插件

    Echo.js 是一个独立的延迟加载图片的 JavaScript 插件.Echo.js 不依赖第三方库,压缩后不到1KB大小. 延迟加载是提高网页首屏显示速度的一种很有效的方法,当图片元素进入窗口可视 ...

  6. 插件介绍 :cropper是一款使用简单且功能强大的图片剪裁jQuery插件。

    简要教程 cropper是一款使用简单且功能强大的图片剪裁jQuery插件.该图片剪裁插件支持图片放大缩小,支持鼠标滚轮操作,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用. c ...

  7. 用最简单的例子实现jQuery图片即时上传

    [http://www.cnblogs.com/Zjmainstay/archive/2012/08/09/jQuery_upload_image.html] 最近看了一些jQuery即时上传的插件, ...

  8. 用代码获取APP启动页图片

    用代码获取APP启动页图片 源码 - swift // // AppleSystemService.swift // Swift-Animations // // Created by YouXian ...

  9. 微信APP长按图片禁止保存到本地

    项目遇到一个问题,在web页面中,禁止长按图片保存, 使用css属性:  img { pointer-events: none; } 或者  img { -webkit-user-select: no ...

随机推荐

  1. QML加载gif

    AnimatedImage { anchors.fill: parent source: "qrc:/img/timg.gif" }

  2. Qwidget::update

    void QWidget::update ()分析重绘事件激活 1看看手册中这段话 void QWidget::update () [slot] Updates the widget unless u ...

  3. (六)利用JackSon工具将JSON文件和对象互转

    1. 需要下载JackSon工具,并导入到: 2. 编写html页面: <!DOCTYPE html> <html> <head> <meta charset ...

  4. Mysql安装、查看密码、修改密码、初始化、修改字符类型

    安装mysql 参照python篇一键安装lnmp.安装完之后再按照下面修改密码,修改配置文件,否则安装的时候就修改配置文件会出错. 注意:这也是二进制安装mysql.另一种二进制安装容易出错,生产环 ...

  5. 求数值的n次方根

    二分法 float SqrtByBisection(float n) //用二分法 { if(n<0) //小于0的按照你需要的处理 return n; float mid,last; floa ...

  6. nice-validator表单验证插件

    nice-validator表单验证插件的简单使用 前言 前端表单校验是过滤无效数据.假数据.有毒数据的第一步,是数据安全的第一道关卡,虽然我们不能100%相信客户端提交的数据(真正的校验还得在服务端 ...

  7. ThinkPHP 5 文件上传及指定宽高生成缩略图公共方法

    这个是非常常用的案例,ThinkPHP 5 文件上传及指定宽高生成缩略图公共方法/** * 单文件上传 * name:表单上传文件的名字 * ext: 文件允许的后缀,字符串形式 * path:文件保 ...

  8. 解决 OpenCV with CUDA 编译提示缺少 nvcuvid.h 的问题

    系统环境: 操作系统:Ubuntu 18.04.01 显卡型号:GeForce GTX 1060 6G CMake 版本:3.10.2 GCC 版本:7.4.0 GNU Make 版本:4.1 CUD ...

  9. 最新 百合佳缘java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 百合佳缘等10家互联网公司的校招Offer,因为某些自身原因最终选择了 百合佳缘.6.7月主要是做系统复习.项目复盘.Le ...

  10. yum 安装 epel-release 后出现yum doesn’t have enough cached data to continue错误的解决方案

    工作中需要部署docker,由于是内网环境,无法直接访问外网,于是考虑在内网搭建yum私有源进行安装,内网服务器操作系统为centos 7.4.根据docker的官方安装方式进行安装时,要求安装 ep ...