收集 iPhone 个图书馆在两个确切日期之间拍摄的照片

Collect Photos of iPhone Library taken between two precise dates

我正在尝试在 swift 中创建一个简单的控制器,它允许我从库中收集在两个精确日期之间拍摄的照片,例如 2015 年 2 月 15 日和 2015 年 2 月 18 日。 在搜索过程中,我阅读了 iOS 的照片框架,我想知道是否有一种简单的方法可以根据上述日期使用此类框架查询照片库。我还想获取图像元数据,例如地理位置。如果我能用相同的框架做到这一点,那就太好了 感谢您的回答

要收集两个日期之间的照片,首先您需要创建 NSDates 来表示日期范围的开始和结束。这是一个 NSDate 扩展(来自 ),它可以从它们的字符串表示中创建日期:

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)
    }
}

然后使用 NSDatePHFetchResultPHFetchOptions 创建谓词。

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)
                    }
                })
            }
        }
    }
}

首先我要感谢 '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)")

}

编码愉快..