<!--
{
  "availability" : [
    "iOS: 8.0.0 -",
    "iPadOS: 8.0.0 -",
    "macCatalyst: 13.1.0 -",
    "macOS: 10.13.0 -",
    "tvOS: 10.0.0 -",
    "visionOS: 1.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "PhotoKit",
  "identifier" : "/documentation/Photos/PHFetchResultChangeDetails/init(from:to:changedObjects:)",
  "metadataVersion" : "0.1.0",
  "role" : "Initializer",
  "symbol" : {
    "kind" : "Initializer",
    "modules" : [
      "Photos"
    ],
    "preciseIdentifier" : "c:objc(cs)PHFetchResultChangeDetails(cm)changeDetailsFromFetchResult:toFetchResult:changedObjects:"
  },
  "title" : "init(from:to:changedObjects:)"
}
-->

# init(from:to:changedObjects:)

Creates a change details object that summarizes the differences between two fetch results.

```
convenience init(from fromResult: PHFetchResult<ObjectType>, to toResult: PHFetchResult<ObjectType>, changedObjects: [ObjectType])
```

## Parameters

`fromResult`

A fetch result to be treated as the “before” state in the resulting change details object.

`toResult`

A fetch result to be treated as the “after” state in the resulting change details object.

`changedObjects`

An collection of objects to manually note as changed between the two fetch results.

## Return Value

A change details object.

## Discussion

Typically, you use the [`PHChange`](/documentation/Photos/PHChange) class to retrieve [`PHFetchResultChangeDetails`](/documentation/Photos/PHFetchResultChangeDetails) objects describing any changes that have occurred since you performed a fetch, but you can also use this method to get a change details object that summarizes the difference between two arbitrary [`PHFetchResult`](/documentation/Photos/PHFetchResult) objects. In this case, Photos cannot automatically determine when the same objects are present in both fetch results but those objects’ content has changed, so the [`changedIndexes`](/documentation/Photos/PHFetchResultChangeDetails/changedIndexes) and [`changedObjects`](/documentation/Photos/PHFetchResultChangeDetails/changedObjects) properties are empty.

However, you can use the `changedObjects` parameter to manually note objects as changed. For example, consider a view controller that maintains a base fetch result representing a list of albums, and a transient collection that filters the list according to the user’s search terms. For this workflow, you might use a method like the following:

```swift
func filteredResult(for fetchResult: PHFetchResult<PHCollection>) -> PHFetchResult<PHCollection> {    var filteredAlbums = [PHCollection]()
    fetchResult.enumerateObjects { collection, _, _ in
        if let title = collection.localizedTitle, let searchText = self.searchBar.text, title.hasPrefix(searchText) {
            filteredAlbums.append(collection)
        }
    }
    let filteredList = PHCollectionList.transientCollectionList(with: filteredAlbums, title: nil)
    return PHCollection.fetchCollections(in: filteredList, options: nil)
}
```

Because transient collections are not stored in the photo library, Photos cannot provide change details for fetch results against a transient collection. The [`photoLibraryDidChange(_:)`](/documentation/Photos/PHPhotoLibraryChangeObserver/photoLibraryDidChange(_:)) method provides change details for the base fetch result, which you can use to request change details for the filtered fetch result:

```swift
func photoLibraryDidChange(_ change: PHChange) {
    // This method may be called on a background queue; use the main queue to update the UI.
    DispatchQueue.main.async {
        guard let fetchResultChangeDetails = change.changeDetails(for: self.baseFetchResult)
            else { return }

        // Get the new base fetch result and filter it to get a new filtered result.
        self.baseFetchResult = fetchResultChangeDetails.fetchResultAfterChanges
        let previousFilteredResult = self.filteredFetchResult!
        self.filteredFetchResult = self.filteredResult(for: self.baseFetchResult)

        // Get the changed objects between the original and new base fetches
        // and use them for marking changes between the filtered fetches.
        let filteredChangeDetails = PHFetchResultChangeDetails(
            from: previousFilteredResult,
            to: self.filteredFetchResult,
            changedObjects: fetchResultChangeDetails.changedObjects)

        // Use the filtered change details to update the UI.
        self.updateView(for: filteredChangeDetails)
    }
}
```

Because you provide the [`changedObjects`](/documentation/Photos/PHFetchResultChangeDetails/changedObjects) array from the original change details when calling the [`init(from:to:changedObjects:)`](/documentation/Photos/PHFetchResultChangeDetails/init(from:to:changedObjects:)) method, Photos can provide a summary of differences between the filtered fetch results that includes [`changedIndexes`](/documentation/Photos/PHFetchResultChangeDetails/changedIndexes) and [`changedObjects`](/documentation/Photos/PHFetchResultChangeDetails/changedObjects) information. You can then use this information for efficiently updating your app’s interface — for an example of how to do this, see [`PHPhotoLibraryChangeObserver`](/documentation/Photos/PHPhotoLibraryChangeObserver).

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)