Determine If the Access to Photo Library Is Set or Not - PHPhotolibrary

Determine if the access to photo library is set or not - PHPhotoLibrary

Check +[PHPhotoLibrary authorizationStatus] – if not set, it will return PHAuthorizationStatusNotDetermined. (You can then request access using +requestAuthorization: on the same class.)

check for authorization status to photo library

ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];

The docs for ALAuthorizationStatus show the possible values. This API only works under iOS 6.0 or later.

Swift how to show alert to request permission for photo library?

If the status be on . notDetermined, so the app automatically shows the alert to the user, but if the status was on .restricted or denied you cannot do anything to ask user again for the access to the photos like the original one, but you can make a custom alert and ask user to give you access to the photos and if user accepted your request, lead the user to the setting and ask him to enable your access manually!

iOS11 photo library access is possible even if settings are set to never

Okay, you can sort of piece this together from answers and comments already, but to try to tell a more complete story...


In iOS 11, UIImagePickerController runs as a separate process from your app. That means:

  1. Your app can't see the user's whole Photos library — it gets read-only access just for whichever asset(s) the user chooses in the image picker.
  2. Because of (1), your app doesn't need the standard privacy authorization for Photos library access. The user explicitly chooses a specific asset (or multiple) for use in your app, which means the user is granting your app permission to read the asset(s) in question.

You can see more about this in the WWDC17 talk on PhotoKit.

(By the way, this model matches what you've seen in the Contacts framework since iOS 9; if you show contact picker, your app only gets a one-time drop of contact information for the contact(s) the user picked, not ongoing read/write access to the Contacts database, so the contact picker doesn't require special privacy permission.)


PHPhotoLibrary and its authorization status reflect the global read/write permission for Photos access that users can control from Settings > Privacy. (That's the one where your Info.plist needs NSPhotoLibraryUsageDescription.) Any use of the PHPhotoLibrary API requires this permission, regardless of whether your app's use of that API is only for writing or only for reading. This has been true since PhotoKit was introduced in iOS 8.

If you're not using PHPhotoLibrary, PHAsset, etc, there are narrower permission options that are new in iOS 11 (and not part of the Photos.framework API):

  • As noted above, UIImagePickerController doesn't need blanket Privacy Settings permission because each use grants one-time read access for the specific assets chosen.
  • If you need only to add new assets to the Photos library, use UIImageWriteToSavedPhotosAlbum or UISaveVideoAtPathToSavedPhotosAlbum. With those you can put NSPhotoLibraryAddUsageDescription in your Info.plist — then the system's Privacy Settings will make clear to the user that they're not giving your permission to see or modify existing assets, only to add new ones.

    If the user grants add-only permission, it applies only to those UIKit functions — attempting to use PHPhotoLibrary will still prompt for (and require the Info.plist key for) read/write access.

    See this part of the WWDC17 talk for more on the add-only privacy setting.

In Swift 4.1 how do you request write-only permission for the photo library?

Unfortunately, access control for PhotoKit is not separated between read and write. If you look at PHAuthorizationStatus, there are only cases where full access is granted. No write only option.

NSPhotoLibraryUsageDescription is the only privacy message you can configure, so you can let the user know that you are only writing, not reading. App store review will make sure that is true.

Edit: also see Detect add photos only permission for iOS 11+

Image gallery not show after request access permission

The way that UICollectionView.rx.items works is that it observes its dataSource. When the dataSource emits a new array, the items operator will reload the collection view and call its closure for each item.

Since you are using just as your data source, only one array is emitted and the collection view never changes. You have to tie the source to the change observer to get it to work. Here is a working example:

extension PhotosViewController { // a UICollectionViewController
func connect(disposeBag: DisposeBag) {
// initial fetch result
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
let initialFetchResult = PHAsset.fetchAssets(with: allPhotosOptions)

let assets = PHPhotoLibrary.shared().rx.registerChangeObserver()
// when a change is observed, we need to update the fetchResult
.scan(initialFetchResult) { oldResult, change in
guard let changes = change.changeDetails(for: oldResult) else { return oldResult }
return changes.fetchResultAfterChanges
}
// but first send the initial asset fetch to the collection view
.startWith(initialFetchResult)
// and get the assets out of the fetch result.
.map { $0.objects(at: IndexSet(0 ..< $0.count)) }

collectionView.dataSource = nil
assets
.observe(on: MainScheduler.instance)
.bind(to: collectionView.rx.items(cellIdentifier: "GridViewCell", cellType: GridViewCell.self)) { _, asset, cell in
cell.configure(asset: asset)
}
.disposed(by: disposeBag)
}
}

extension Reactive where Base: PHPhotoLibrary {
// not actually needed, but I provided it as an example.
static func requestAuthorization() -> Observable {
Observable.create { observer in
Base.requestAuthorization { status in
observer.onNext(status)
observer.onCompleted()
}
return Disposables.create()
}
}

// this sets up the change observer. Note, your VC isn't the observer.
func registerChangeObserver() -> Observable {
Observable.create { [base] observer in
let changeObserver: RxPhotoLibraryChangeObserver = .init(observer: observer)
base.register(changeObserver)
return Disposables.create { base.unregisterChangeObserver(changeObserver) }
}
}
}

// this is the change observer used in the above.
final class RxPhotoLibraryChangeObserver: NSObject, PHPhotoLibraryChangeObserver {
let observer: AnyObserver
init(observer: AnyObserver) {
self.observer = observer
}

func photoLibraryDidChange(_ changeInstance: PHChange) {
observer.onNext(changeInstance)
}
}


Related Topics



Leave a reply



Submit