在两个确定日期之间收集 iPhone 图库中拍摄的照片。

4
我正在尝试在Swift中创建一个简单的控制器,使我能够收集从两个精确日期之间拍摄的照片,例如2015年2月15日和2015年2月18日。在搜索过程中,我了解到iOS的Photo Framework,并想知道是否有一种简单的方法可以使用该框架根据上述日期查询照片库。我还想获取图像元数据,例如地理位置等。如果我可以使用相同的框架完成这些操作,那就太好了。感谢您的回答。

你有没有查看过这个网址:https://dev59.com/hGDVa4cB1Zd3GeqPdXPf? - Teja Nandamuri
2
@Mr.T 那个答案已经过时了。现在最好使用Photos框架来替代Assets Library框架。 - Lyndsey Scott
2个回答

7

要在两个日期之间收集照片,首先需要创建代表日期范围的开始和结束的NSDate。这里是一个NSDate扩展(来自https://dev59.com/PGAf5IYBdhLWcg3w_Gyr#24090354),它可以从它们的字符串表示中创建这些日期:

extension NSDate {
    convenience
    init(dateString:String) {
        let dateStringFormatter = NSDateFormatter()
        dateStringFormatter.dateFormat = "MM-dd-yyyy"
        dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        let d = dateStringFormatter.dateFromString(dateString)!
        self.init(timeInterval:0, sinceDate:d)
    }
}

然后使用NSDate创建一个谓词,用于PHFetchResult的PHFetchOptions。
import Photos

class ViewController: UIViewController {

    var images:[UIImage] = [] // <-- Array to hold the fetched images

    override func viewDidLoad() {
        fetchPhotosInRange(NSDate(dateString:"04-06-2015"), endDate: NSDate(dateString:"04-16-2015"))
    }

    func fetchPhotosInRange(startDate:NSDate, endDate:NSDate) {

        let imgManager = PHImageManager.defaultManager()

        let requestOptions = PHImageRequestOptions()
        requestOptions.synchronous = true
        requestOptions.networkAccessAllowed = true

        // Fetch the images between the start and end date
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "creationDate > %@ AND creationDate < %@", startDate, endDate)

        images = []

        if let fetchResult: PHFetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) {
            // If the fetch result isn't empty,
            // proceed with the image request
            if fetchResult.count > 0 {
                // Perform the image request
                for var index = 0 ; index < fetchResult.count ; index++ {
                    let asset = fetchResult.objectAtIndex(index) as! PHAsset
                    imgManager.requestImageDataForAsset(asset, options: requestOptions, resultHandler: { (imageData: NSData?, dataUTI: String?, orientation: UIImageOrientation, info: [NSObject : AnyObject]?) -> Void in
                        if let imageData = imageData {
                            if let image = UIImage(data: imageData) {
                            // Add the returned image to your array
                                self.images += [image]
                            }
                        }
                        if self.images.count == fetchResult.count {
                            // Do something once all the images 
                            // have been fetched. (This if statement
                            // executes as long as all the images
                            // are found; but you should also handle
                            // the case where they're not all found.)
                        }
                    })
                }
            }
        }
    }
}

更新至Swift 3:


import UIKit
import Photos

class ViewController: UIViewController {

    var images:[UIImage] = [] // <-- Array to hold the fetched images

    override func viewDidLoad() {
        let formatter = DateFormatter()
        formatter.dateFormat = "MM-dd-yyyy"
        fetchPhotosInRange(startDate: formatter.date(from: "04-06-2015")! as NSDate, endDate: formatter.date(from: "04-16-2015")! as NSDate)
    }

    func fetchPhotosInRange(startDate:NSDate, endDate:NSDate) {

        let imgManager = PHImageManager.default()

        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = true
        requestOptions.isNetworkAccessAllowed = true

        // Fetch the images between the start and end date
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "creationDate > %@ AND creationDate < %@", startDate, endDate)

        images = []

        let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
        // If the fetch result isn't empty,
        // proceed with the image request
        if fetchResult.count > 0 {
            // Perform the image request
            for index in 0  ..< fetchResult.count  {
                let asset = fetchResult.object(at: index)
                imgManager.requestImageData(for: asset, options: requestOptions, resultHandler: { (imageData: Data?, dataUTI: String?, orientation: UIImageOrientation, info: [AnyHashable : Any]?) -> Void in
                    if let imageData = imageData {
                        if let image = UIImage(data: imageData) {
                            // Add the returned image to your array
                            self.images += [image]
                        }
                    }
                    if self.images.count == fetchResult.count {
                        // Do something once all the images
                        // have been fetched. (This if statement
                        // executes as long as all the images
                        // are found; but you should also handle
                        // the case where they're not all found.)
                        print(self.images)
                    }
                })
            }
        }
    }
}

@Lindsey 哎呀,我得去睡觉了... 我被我在 Stack Overflow 上打开的所有文章搞混了。 - Vincent Rolea
@GeorgeAsda 我已经将代码更新到Swift 3,但是没有看到任何错误...你指的是哪些错误? - Lyndsey Scott
之前的代码片段在Swift 3中引发了错误。我还没有测试过更新后的代码。 - George Asda
@GeorgeAsda 在Swift 3中无法编译是因为它不是Swift 3的代码。这个下投票的原因有点奇怪,我只是这么说...(并不是说我介意,也没有必要改变什么。只是有点困惑为什么有人会在使用需要另一种语言的编译器时对一个语言的答案进行下投票。) - Lyndsey Scott
能正常工作吗?我们可以根据日期从照片库中获取照片吗? - AppleBee
显示剩余4条评论

0
首先,我想对“Lyndsey Scott”的出色代码表示感谢。它真的很有帮助。可能会在一些最新的编译器中返回错误,因为代码需要稍作更新。所以在这里,我提供了最新的更新代码,以使Lyndsey的代码在最新的Swift 4.0或更高版本的编译器中无错误。
extension NSDate {
convenience
init(dateString:String) {
    let dateStringFormatter = DateFormatter()
    dateStringFormatter.dateFormat = "MM-dd-yyyy"
    dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale?
    let d = dateStringFormatter.date(from: dateString)!
    self.init(timeInterval: 0, since: d)
}

}

然后使用NSDates来为PHFetchResult的PHFetchOptions创建一个谓词。
import UIKit
import Photos

class ViewController: UIViewController {

var images:[UIImage] = [] // <-- Array to hold the fetched images

override func viewDidLoad() {
    super.viewDidLoad()
    fetchPhotosInRange(startDate: NSDate(dateString:"07-15-2018"), endDate: NSDate(dateString:"07-31-2018"))

}

func fetchPhotosInRange(startDate:NSDate, endDate:NSDate)  {

    let imgManager = PHImageManager.default()

    let requestOptions = PHImageRequestOptions()
    requestOptions.isSynchronous = true
    requestOptions.isNetworkAccessAllowed = true

    // Fetch the images between the start and end date
    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "creationDate > %@ AND creationDate < %@", startDate, endDate)

    images = []

    if let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions) {
        // If the fetch result isn't empty,
        // proceed with the image request
        if fetchResult.count > 0 {
            // Perform the image request
           for (index) in 0 ..< fetchResult.count {

           // for var index = 0 ; index < fetchResult.count ; index++ {
            let asset = fetchResult.object(at: index)
            // Request Image
            imgManager.requestImageData(for: asset, options: requestOptions, resultHandler: { (imageData, str, orientation, info) -> Void in

                    if let imageData = imageData {
                        if let image = UIImage(data: imageData) {
                            // Add the returned image to your array
                            self.images += [image]
                        }
                    }
                    if self.images.count == fetchResult.count {
                        // Do something once all the images
                        // have been fetched. (This if statement
                        // executes as long as all the images
                        // are found; but you should also handle
                        // the case where they're not all found.)
                    }
                })
            }
        }
    }
    print("images ==>\(images)")

}

开心编程..


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接