PHFetchOptions include only photos from iPhone camera - ios

Right now I use that to exclude Screenshots:
let options = PHFetchOptions()
options.predicate = NSPredicate(format: "NOT (mediaSubtype & \(PHAssetMediaSubtype.photoScreenshot.rawValue) != 0)")
var fetchResult: PHFetchResult<PHAsset> = fetchResult =
PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)
But I want to include only photos that were taken from iPhone Camera (not photos that were saved from other applications like Skype and so on). Is it possible?

Related

Get Video or Video Info Without open Gallery Swift

I am trying to get Video without open Gallery or UIImagePickerControllerlike I got success in getting images without open gallery. Is there any way to get files without open UIImagePickerController.
Can someone please explain to me how to get files without open UIImagePickerController. Any help would be greatly appreciated.
Thanks in advance.
For example, using the following code, you can get the latest user video:
import Photos
let options = PHFetchOptions()
options.fetchLimit = 1
let sortDescriptor = NSSortDescriptor(key: "creationDate", ascending: false)
options.sortDescriptors = [sortDescriptor]
let fetchResult = PHAsset.fetchAssets(with: .video, options: options)
if fetchResult.count == 0 {
// user has no video...
return
}
let asset = fetchResult[0]
let requestOptions = PHVideoRequestOptions()
let manager = PHImageManager.default()
Then, if you want to get the video itself, use the following code:
manager.requestAVAsset(forVideo: asset, options: requestOptions, resultHandler: { oAsset, oAudioMix, oDict in
if let urlAsset = oAsset as? AVURLAsset {
let url = urlAsset.url
// use URL to get file content
}
})
Otherwise, if you just want to play the video, use the following code:
manager.requestPlayerItem(forVideo: asset, options: requestOptions, resultHandler: { oPlayerItem, oDict in
// do something with oPlayerItem
})
For more information you can read this

How to fetch all assets from iPhone apart from camera roll?

How to fetch assets from all albums including images and videos ?
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
let allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
This code will fetch only images from camera roll.
You can use this code to fetch all assets from iPhone.
PHPhotoLibrary.shared().register(self as PHPhotoLibraryChangeObserver)
if fetchResult == nil {
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
fetchResult = PHAsset.fetchAssets(with: allPhotosOptions)
}
we can fetch all photos including sync albums and user albums.
let fetchOptions = PHFetchOptions()
fetchOptions.includeAssetSourceTypes = [.typeUserLibrary, .typeiTunesSynced, .typeCloudShared]
let fetchResult = PHAsset.fetchAssets(with: fetchOptions)
fetchResult will be having all photos and videos in all albums.

Fetch only PHAssetCollections containing at least one photo

In iOS PhotoKit, I can fetch all non-empty albums like this:
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "estimatedAssetCount > 0")
let albumFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: albumFetchOptions)
albumFetchResult.enumerateObjects({ (collection, _, _) in
// Do something with the album...
})
Then I can get only photos from the album like this:
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetResourceType.photo.rawValue)
let fetchResults = PHAsset.fetchAssets(in: collection, options: fetchOptions)
But the first part can give me albums with only videos, which means that after I apply the predicate to the second part, the album will be empty. Is there a way to filter out those albums in the first part, before I start using them?
It seems that collections cannot be filtered like this without also fetching the items in the collections. See the docs for available fetch options; none allow filtering by number of a specific type of media.
The way I would achieve this is by fetching all albums created by the user, and then fetching the assets from the albums with a predicate that returns only images.
So to put it in code:
var userCollections: PHFetchResult<PHAssetCollection>!
// Fetching all PHAssetCollections with at least some media in it
let options = PHFetchOptions()
options.predicate = NSPredicate(format: "estimatedAssetCount > 0")
// Performing the fetch
userCollections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumRegular, options: options)
Next, fetch the assets from a collection that are images by specifying a predicate:
// Getting the specific collection (I assumed to use a tableView)
let collection = userCollections[indexPath.row]
let optionsToFilterImage = PHFetchOptions()
optionsToFilterImage.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Image.rawValue)
// Fetching the asset with the predicate to filter just images
let justImages = PHAsset.fetchAssets(in: collection, options: optionsToFilterImage)
Lastly, count the number of images:
if justImages.count > 0 {
// Display it
} else {
// The album has no images
}

How to share video to Facebook using URL scheme

I'm trying to enable users to share the most recent video from their Photos gallery to Facebook. I've looked at http://wiki.akosma.com/IPhone_URL_Schemes#Facebook to see the URL schemes, but I can't figure out the proper URL to create in my app. I have done this successfully for Instagram, here is what it looks like:
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let fetchResult = PHAsset.fetchAssetsWithMediaType(.Video, options: fetchOptions)
if let lastAsset = fetchResult.firstObject as? PHAsset {
let localIdentifier = lastAsset.localIdentifier
let u = "instagram://library?LocalIdentifier=" + localIdentifier
let url = NSURL(string: u)!
if UIApplication.sharedApplication().canOpenURL(url) {
UIApplication.sharedApplication().openURL(NSURL(string: u)!)
}
}
What is the proper way to do this successfully?

PHFetchOptions() Photos Only Using PHAsset & PHAssetCollection

I am using a chunk from Apple's sample code here:
override func awakeFromNib() {
// Create a PHFetchResult object for each section in the table view.
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let allPhotos = PHAsset.fetchAssetsWithOptions(allPhotosOptions)
let smartAlbums = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .AlbumRegular, options: nil)
let topLevelUserCollections = PHCollectionList.fetchTopLevelUserCollectionsWithOptions(nil)
// Store the PHFetchResult objects and localized titles for each section.
self.sectionFetchResults = [allPhotos, smartAlbums, topLevelUserCollections]
self.sectionLocalizedTitles = ["", NSLocalizedString("Smart Albums", comment: ""), NSLocalizedString("Albums", comment: "")]
PHPhotoLibrary.sharedPhotoLibrary().registerChangeObserver(self)
}
This lists all Albums successfully.
What I Need:
I want to only list albums with photos, exclude videos. Also, exclude video's from getting listed inside of albums, such as inside "All Photos".
What I tried:
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Image.rawValue)
This causes to crash saying 'Unsupported predicate in fetch options: mediaType == 1'
I know this is a very late answer, but in case someone like me gets here, you should use this method to retrieve a media type. In this case PHAssetMediaType.image
func fetchAssets(with mediaType: PHAssetMediaType, options: PHFetchOptions?) -> PHFetchResult<PHAsset>
So in Swift 5 it writes as
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
fetchResult = PHAsset.fetchAssets(with: .image, options: allPhotosOptions)
So far it works fine to me :
let allAlbums = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumRegular, options: nil)
let someAlbum = allAlbums.object(at: 0)
let onlyPhotoOption = PHFetchOptions()
onlyPhotoOption.predicate = NSPredicate(format: "mediaType == %i", PHAssetMediaType.image.rawValue)
let photos = PHAsset.fetchAssets(in: someAlbum, options: onlyPhotoOption)

Resources