4

I have added NSPhotoLibraryAddUsageDescription as well as NSPhotoLibraryUsageDescription in info.plist file of my project. While trying to create album or add image to photo library following error is coming

This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

I have tried some swift library like PhotosHelper.as well to do that but still I am facing same Issue

Following is code that I am following

import UIKit
import Photos

class PhotoLibraryManager
{


private class func fetchAlbumWithName(albumName:String)->PHAssetCollection?
{
    let fetchPredicate = PHFetchOptions()
    fetchPredicate.predicate = NSPredicate(format: "title == '" + albumName + "'")
    let fetchResult = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.album, subtype: PHAssetCollectionSubtype.albumRegular, options: fetchPredicate)
    return fetchResult.firstObject
}

/**
 This function requests for authorization to use the photo gallery and adds the image in the album both of which are specified.If the album does not exist it creates a new one and adds the image in that
 - Parameters:
 - image:The image to be inserted
 - albumName:The name of the album in which the image is to be inserted
 */


class func saveImageToPhone(image:UIImage,albumName:String)
{
    PHPhotoLibrary.requestAuthorization({(status:PHAuthorizationStatus)->Void in
        switch status
        {
        case PHAuthorizationStatus.authorized:
            insertImageAfterAuthorization(image: image,albumName: albumName)
        default:
            print("Unable To Access Photo Library")
        }
    })
}

/**
 This function fetches the specified album from the photo library if present or creates a new one
 - Parameters:
 - image:The image to be inserted
 - albumName:The name of the album in which the image is to be inserted
 */


private class func insertImageAfterAuthorization(image:UIImage,albumName:String)
{
    let album = fetchAlbumWithName(albumName: albumName)
    guard let albumToBeInserted = album else{
        print("Creating A New Album \(albumName)")
        PHPhotoLibrary.shared().performChanges({
            PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName)
        }, completionHandler: {(success:Bool,error:Error?)->Void in
            guard let errorObj = error else{
                let album = fetchAlbumWithName(albumName: albumName)
                guard let createdAlbum = album else{
                    print("Album Not Created")
                    return
                }
                addImageIntoAlbum(image: image,album: createdAlbum)
                return
            }
            print(errorObj.localizedDescription)
            return
        })
        return
    }
    addImageIntoAlbum(image: image,album: albumToBeInserted)
}

/**
 This function adds an image into the album specifed
 - Parameters:
 - image:The image to be added
 - album:The album in which the image is to inserted
 */

private class func addImageIntoAlbum(image:UIImage,album:PHAssetCollection)
{
    PHPhotoLibrary.shared().performChanges({
        let imgCreationRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
        print(imgCreationRequest)
        let albumRequest = PHAssetCollectionChangeRequest(for: album)
        guard let albumSpecificationRequest = albumRequest , let placeholderObjForImg = imgCreationRequest.placeholderForCreatedAsset else{
            print("Image Could Not Be Added")
            return
        }
        let arrAlbumSpecificationRequest:NSArray = [placeholderObjForImg]
        albumSpecificationRequest.addAssets(arrAlbumSpecificationRequest)
        //            albumSpecificationRequest.addAssets([placeholderObjForImg])
    }, completionHandler: {(success:Bool,error:Error?)->Void in
        guard let errorObj = error else{
            return
        }
        print(errorObj.localizedDescription)
    })
}

}

Here is my info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>NewApp</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
    <string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>NSContactsUsageDescription</key>
<string>Connect People</string>
<key>NSCameraUsageDescription</key>
<string>Video Call</string>
<key>NSMicrophoneUsageDescription</key>
<string>For Audio Call</string>
<key>NSSiriUsageDescription</key>
<string>Siri Uses Test</string>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationPortraitUpsideDown</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
    <string>fetch</string>
    <string>remote-notification</string>
    <string>voip</string>
</array>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo Use</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Photo Use</string>
<key>NSUserActivityTypes </key>
<array>
    <string>INStartAudioCallIntent</string>
    <string>INStartVideoCallIntent</string>
</array>
</dict>
</plist>

Thanks in advance for the help.

Afsar edrisy
  • 1,985
  • 12
  • 28

3 Answers3

6

Open your info.plist as a source code and paste the following in it.

<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library.</string>

<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app requires read and write access to the photo library.</string>
Atmaram
  • 494
  • 4
  • 14
4

Open your info.plist by Source Code or Property List.

For Property List,you can just add a key NSPhotoLibraryUsageDescription and its value This app requires access to the photo library.

For Source Code,you can add the follow code to the plist.And the code must be between the <dict> and the </dict>.

<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library.</string>

The value for the key is actually a kind of desctription, so you can make a description all by youself.But make sure that the users of your app can understand the description you make easily.

And for camera,you can use the follow code:

<key>NSCameraUsageDescription</key>
<string>This app requires access to the camera.</string>

More keys: Cocoa keys.

Lynx
  • 381
  • 1
  • 13
2

Finally I have fixed the issue, I don't know what was the reason. after so much of struggle, I got idea to try in different project so, I created a new project and copy info.plist & other required swift and story bored files from old project to new project & it works.

Afsar edrisy
  • 1,985
  • 12
  • 28