Bug 37734 - PHPhotoLibrary.SharedPhotoLibrary returning null
Summary: PHPhotoLibrary.SharedPhotoLibrary returning null
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: XI 9.1 (iOS 9.1)
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2016-01-15 17:12 UTC by ryan.brooks
Modified: 2016-04-12 17:37 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description ryan.brooks 2016-01-15 17:12:38 UTC
Accessing the PHPhotoLibrary.SharedPhotoLibrary singleton is returning null.

About Xamarin Studio info below:
=== Xamarin Studio ===

Version 5.9.8 (build 0)
Installation UUID: 8b549871-9471-4382-8581-9b2fe2391dad
	Mono 4.0.5 ((detached/1d8d582)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 400050001

=== Apple Developer Tools ===

Xcode 7.1 (9079)
Build 7B91b

=== Xamarin.iOS ===

Version: (Business Edition)
Hash: 1f068b4
Branch: master
Build date: 2015-10-27 18:59:21-0400

=== Xamarin.Mac ===

Not Installed

=== Xamarin.Android ===

Not Installed

=== Xamarin Android Player ===

Not Installed

=== Build Information ===

Release ID: 509080000
Git revision: cc5f6e5658589ca7f46210c57fad947e75f30abd
Build date: 2015-10-21 19:27:41-04
Xamarin addins: d77f191bd7d3451adf837b85b38f2b7c60004400

=== Operating System ===

Mac OS X 10.11.2
Darwin mavirnens-mini.amer.corp.natinst.com 15.2.0 Darwin Kernel Version 15.2.0
    Fri Nov 13 19:56:56 PST 2015
    root:xnu-3248.20.55~2/RELEASE_X86_64 x86_64
Comment 1 Sebastien Pouliot 2016-01-15 19:26:24 UTC
This works fine from our unit tests. Did you call RequestAuthorization ? What's returned from AuthorizationStatus ?

Please attach a self-contained test case if this is not authorization related and we'll have a look asap.
Comment 2 ryan.brooks 2016-01-15 21:01:37 UTC
I went and created a test Single View Controller application (both in Xamarin and in native XCode) to test with authorization.

The test went as following for the first time running the program: 

PHPhotoLibrary.AuthorizationStatus -> NotDetermined
var phPhotoLibrary = PHPhotoLibrary.SharedPhotoLibrary -> not null
PHPhotoLibrary.RequestAuthorization((status) => /* status */) -> status prints

Running the same series of events in the corrupted project yielded:

PHPhotoLibrary.AuthorizationStatus -> NotDetermined
var phPhotoLibrary = PHPhotoLibrary.SharedPhotoLibrary -> null
PHPhotoLibrary.RequestAuthorization((status) => /* status */) -> handler is NEVER called

I was able to get the class to behave correctly (not null) by completely removing all project files, re-synced and building the project fresh.

I've found that I am not the first person to experience this in Xamarin : http://stackoverflow.com/questions/33232286/saving-uiimage-in-the-device-photos-app-xamarin-mono
Comment 3 Sebastien Pouliot 2016-01-20 18:49:42 UTC
I do not think it's related to Xamarin. There's nothing we can't do hack around iOS permissions.

This looks like the application, on that device, got refused the permission when it was first executed. Further execution won't ask again [1] and the user must use the Settings app if he wants to change the permission.

If the application is totally deleted or if another bundle id is used (e.g. new project) then the application will ask again (as it's a different app as far as iOS is concerned).

note: the stackoverflow link is likely hitting the same condition (not Xamarin specific) where the permission was not granted. In such case `SharedPhotoLibrary` will be null.

[1] https://developer.apple.com/library/ios/documentation/Photos/Reference/PHPhotoLibrary_Class/
Comment 4 ryan.brooks 2016-01-20 19:49:48 UTC
"permission was not granted. In such case `SharedPhotoLibrary` will be null." is not a correct statement regarding the behavior of PHPhotoLibrary.

The PHPhotoLibrary.SharedPhotoLibrary should return a non-null reference regardless of PHAuthorizationStatus(NotDetermined, Restricted, Denied, Authorized).

Changing permission should change the PHAuthorizationStatus on the singleton but it should not dictate whether or not the singleton is null.  This singleton should never be null.

Testing on native iOS and a fresh Xamarin solution clearly show this behavior.
Comment 5 Damon Bohls 2016-01-20 20:17:26 UTC
> note: the stackoverflow link is likely hitting the same condition (not Xamarin specific) where the permission was not granted. In such case `SharedPhotoLibrary` will be null.

This is not correct. I can verify that SharedPhotoLibrary is non-null even after having denied permission.

I do not know if there is ever a valid case for SharedPhotoLibrary to be null. Perhaps on older versions of iOS before PHPhotoLibrary was introduced (in iOS 8)? I don't know.

It very well may not be Xamarin related, but it is interesting that the only other example we could find of someone encountering a null SharedPhotoLibrary was also someone using Xamarin.iOS.
Comment 6 Sebastien Pouliot 2016-01-20 20:39:58 UTC
While I can't think of a valid (logical) case for a null SharedPhotoLibrary I also cannot see a valid case to use it if permissions were denied. That's definitively not something you can expect to be well tested in iOS and Apple API are not consistent when permissions are refused. Do not consider it safe to use any such API without verifying permissions were first granted.

As for XI the only way to return `null` if is calling the selector returned `nil`, i.e. we do not create the singleton.

Still it's impossible to rule out a bug (in either iOS or XI) that we have not been able to duplicate. Please attach a self-contained test case (like requested in comment #1) and we will investigate.
Comment 7 Damon Bohls 2016-01-20 22:13:27 UTC
That's good advice to avoid accessing SharedPhotoLibrary without authorization.

I'd imagine that SharedPhotoLibrary is a super simple wrapper as far as Xamarin is concerned, and that would mean the singleton is in fact nil as far as iOS is concerned. The question would be, how did the singleton get to be nil and could it have been something that went wrong during the incredibly complex build process. Perhaps some corruption somewhere might cause iOS to think PHPhotoLibrary is unavailable when in fact it is. There is absolutely no way to know this of course; you need a solution that duplicates this behavior. If we ever get in that state again, we'll let you know.
Comment 8 Sebastien Pouliot 2016-04-12 17:37:05 UTC
We have not received further information and will assume this is not an issue anymore. If you can still affected by this please re-open the bug and include the requested information. Thanks.