收集 iPhone 个图书馆在两个确切日期之间拍摄的照片
Collect Photos of iPhone Library taken between two precise dates
我正在尝试在 swift 中创建一个简单的控制器,它允许我从库中收集在两个精确日期之间拍摄的照片,例如 2015 年 2 月 15 日和 2015 年 2 月 18 日。
在搜索过程中,我阅读了 iOS 的照片框架,我想知道是否有一种简单的方法可以根据上述日期使用此类框架查询照片库。我还想获取图像元数据,例如地理位置。如果我能用相同的框架做到这一点,那就太好了
感谢您的回答
要收集两个日期之间的照片,首先您需要创建 NSDate
s 来表示日期范围的开始和结束。这是一个 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)
}
}
然后使用 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)
}
})
}
}
}
}
首先我要感谢 '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)")
}
编码愉快..
我正在尝试在 swift 中创建一个简单的控制器,它允许我从库中收集在两个精确日期之间拍摄的照片,例如 2015 年 2 月 15 日和 2015 年 2 月 18 日。 在搜索过程中,我阅读了 iOS 的照片框架,我想知道是否有一种简单的方法可以根据上述日期使用此类框架查询照片库。我还想获取图像元数据,例如地理位置。如果我能用相同的框架做到这一点,那就太好了 感谢您的回答
要收集两个日期之间的照片,首先您需要创建 NSDate
s 来表示日期范围的开始和结束。这是一个 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)
}
}
然后使用 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)
}
})
}
}
}
}
首先我要感谢 '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)")
}
编码愉快..