Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于creationDate以Swift[更快的方式?]从库中获取所有照片_Swift_Phasset_Photosframework_Phassetslibrary - Fatal编程技术网

基于creationDate以Swift[更快的方式?]从库中获取所有照片

基于creationDate以Swift[更快的方式?]从库中获取所有照片,swift,phasset,photosframework,phassetslibrary,Swift,Phasset,Photosframework,Phassetslibrary,我有一个UICollectionView显示基于最新“creationDate”的图书馆照片。为此,我使用以下代码: struct AssetsData { var creationDate: Date, assetResult: PHFetchResult<PHAsset> } func fetchPhotos() -> [AssetsData] { //Date Formatter let formatter = DateFormatter()

我有一个
UICollectionView
显示基于最新“creationDate”的图书馆照片。为此,我使用以下代码:

struct AssetsData {
    var creationDate: Date, assetResult: PHFetchResult<PHAsset>
}

func fetchPhotos() -> [AssetsData] {
    //Date Formatter
    let formatter = DateFormatter()
    formatter.dateStyle = DateFormatter.Style.medium
    formatter.timeStyle = DateFormatter.Style.none

    //Photos fetch
    let fetchOptions = PHFetchOptions()
    let sortOrder = [NSSortDescriptor(key: "creationDate", ascending: false)]
    fetchOptions.sortDescriptors = sortOrder
    let assetsFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    var arrCreationDate = [Date]()
    var arrDates = [String]()

    //Getting All dates
    for index in 0..<assetsFetchResult.count {
        if let creationDate = assetsFetchResult[index].creationDate {
            let formattedDate = formatter.string(from: creationDate)
            if !arrDates.contains(formattedDate) {
                arrDates.append(formattedDate)
                arrCreationDate.append(creationDate)
            }
        }
    }

    //Fetching Assets based on Dates
    var arrPhotoAssetsData = [AssetsData]()
    for createdDate in arrCreationDate {
        if let startDate = getDate(forDay: createdDate.day, forMonth: createdDate.month, forYear: createdDate.year, forHour: 0, forMinute: 0, forSecond: 0), let endDate = getDate(forDay: createdDate.day, forMonth: createdDate.month, forYear: createdDate.year, forHour: 23, forMinute: 59, forSecond: 59) {
            fetchOptions.predicate = NSPredicate(format: "creationDate > %@ AND creationDate < %@", startDate as NSDate, endDate as NSDate)
            let assetsPhotoFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
            arrPhotoAssetsData.append(AssetsData(creationDate: createdDate, assetResult: assetsPhotoFetchResult))
        }
    }
    return arrPhotoAssetsData
}

func getDate(forDay day: Int, forMonth month: Int, forYear year: Int, forHour hour: Int, forMinute minute: Int, forSecond second: Int) -> Date? {
    var dateComponents = DateComponents()
    dateComponents.day = day
    dateComponents.month = month
    dateComponents.year = year
    dateComponents.hour = hour
    dateComponents.minute = minute
    dateComponents.second = second
    var gregorian = Calendar(identifier: Calendar.Identifier.gregorian)
    gregorian.timeZone = NSTimeZone.system
    return gregorian.date(from: dateComponents)
}
struct AssetsData{
var creationDate:日期,assetResult:PHFetchResult
}
func fetchPhotos()->[AssetsData]{
//日期格式化程序
let formatter=DateFormatter()
formatter.dateStyle=DateFormatter.Style.medium
formatter.timeStyle=DateFormatter.Style.none
//照片获取
让fetchOptions=PHFetchOptions()
let sortOrder=[NSSortDescriptor(键:“creationDate”,升序:false)]
fetchOptions.sortDescriptors=sortOrder
让AssetFetchResult=PHAsset.fetchAssets(带:。图像,选项:fetchOptions)
var arrcreaiondate=[日期]()
var arrDates=[String]()
//获取所有日期
对于0..Date中的索引{
var dateComponents=dateComponents()
dateComponents.day=天
dateComponents.month=月份
dateComponents.year=年
dateComponents.hour=小时
dateComponents.minute=分钟
dateComponents.second=秒
var gregorian=日历(标识符:Calendar.identifier.gregorian)
gregorian.timeZone=NSTimeZone.system
返回公历日期(起始日期:dateComponents)
}

代码运行得很好!但问题是加载10k+照片几乎需要7-9秒。直到6k照片都没有问题,但我真的需要一些有效的方法,以便我可以加载
UICollectionView
中的一些
资产
,其余的我可以稍后添加。我需要的是,无论照片数量多少,都不应该占用更多超过2-3秒。有人能帮忙吗?

假设您有8k张照片。因此,您迭代两个“for”循环,以获取arrCreationDate和arrPhotoAssets数据(这是所需工作量的两倍)

相反,您可以尝试通过一个循环来完成。下面是一个粗略的方法:-

    let assetsFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    let fetchOptions = PHFetchOptions()
    var arrCreationDate = [Date]()
    var arrPhotoAssetsData = [AssetsData]()
    var arrDates = [String]()

     for index in 0..<assetsFetchResult.count {
        if let creationDate = assetsFetchResult[index].creationDate {
            let formattedDate = formatter.string(from: creationDate)
            if !arrDates.contains(formattedDate) {
                //You can convert the formattedDate to actual date here and do a check similar to this, do what you do in the other loop here too
                if(actualDate < actualDateOfTheFirstElementAtArray){
                   arrCreationDate.insert(actualDate, at: 0)
                   fetchOptions.predicate = NSPredicate(format: "creationDate > %@ AND creationDate < %@", startDate as NSDate, endDate as NSDate)
                   let assetsPhotoFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
                   arrPhotoAssetsData.insert(AssetsData(creationDate: createdDate, assetResult: assetsPhotoFetchResult), at: 0)
                }
            }
        }
     }
让AssetFetchResult=PHAsset.fetchAssets(带:。图像,选项:fetchOptions)
让fetchOptions=PHFetchOptions()
var arrcreaiondate=[日期]()
var arrpotoassetsdata=[AssetsData]()
var arrDates=[String]()

对于0中的索引。谢谢。我尝试了,但仍然需要2.09秒才能获取3.1k照片,而我的照片需要1.85秒。很酷,所以您在当前for循环中使用了另一个循环来对元素进行排序?在这种情况下,它是一个嵌套循环,显然比通常的两个单独循环花费更多的时间。您可以尝试使用bin进行排序ary searchUmm..二进制搜索不会像我想的那样有效,因为没有搜索特定日期。我们需要根据从图书馆获取的日期获取所有数据。你认为呢?不,我知道,但我认为你采用了与我想的类似的方法,我的错。我已经编辑了答案。让我知道你的想法…那么你呢刚刚区分了附加部分!这很酷,我会尝试这样做,比如先附加5或6个日期,然后重新加载
UICollectionView
,然后再次附加新数据重新加载它。
        func fetchPhotos() -> [AssetsData] {
    //Date Formatter
    let formatter = DateFormatter()
    formatter.dateStyle = DateFormatter.Style.medium
    formatter.timeStyle = DateFormatter.Style.none

    //Photos fetch
    let fetchOptions = PHFetchOptions()
    let sortOrder = [NSSortDescriptor(key: "creationDate", ascending: false)]
    fetchOptions.sortDescriptors = sortOrder
    let assetsFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    var arrCreationDate = [Date]()
    var arrDates = [String]()
    var arrPhotoAssetsData = [AssetsData]()

    //Getting All dates
    for index in 0..<assetsFetchResult.count {
        if let creationDate = assetsFetchResult[index].creationDate {
            let formattedDate = formatter.string(from: creationDate)
            if !arrDates.contains(formattedDate) {
                arrDates.append(formattedDate)
                arrCreationDate.append(creationDate)
                convertToAssetsDataAndAppend(date: creationDate, fetchOptions: fetchOptions, toArray: &arrPhotoAssetsData)
            }
        }
    }
    return arrPhotoAssetsData
    }

    func convertToAssetsDataAndAppend(date: Date, fetchOptions: PHFetchOptions, toArray: inout [AssetsData]){
    if let startDate = getDate(forDay: date.day, forMonth: date.month, forYear: date.year, forHour: 0, forMinute: 0, forSecond: 0), let endDate = getDate(forDay: date.day, forMonth: date.month, forYear: date.year, forHour: 23, forMinute: 59, forSecond: 59) {
        fetchOptions.predicate = NSPredicate(format: "creationDate > %@ AND creationDate < %@", startDate as NSDate, endDate as NSDate)
        let assetsPhotoFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
        toArray.append(AssetsData(creationDate: date, assetResult: assetsPhotoFetchResult))
    }
}

func getDate(forDay day: Int, forMonth month: Int, forYear year: Int, forHour hour: Int, forMinute minute: Int, forSecond second: Int) -> Date? {
    var dateComponents = DateComponents()
    dateComponents.day = day
    dateComponents.month = month
    dateComponents.year = year
    dateComponents.hour = hour
    dateComponents.minute = minute
    dateComponents.second = second
    var gregorian = Calendar(identifier: Calendar.Identifier.gregorian)
    gregorian.timeZone = NSTimeZone.system
    return gregorian.date(from: dateComponents)
}