jellyfin / Swiftfin

Native Jellyfin Client for iOS and tvOS
Mozilla Public License 2.0
2.55k stars 278 forks source link

tvOS mapping Apple TV users to Jellyfin users #258

Open jorritolthuis opened 2 years ago

jorritolthuis commented 2 years ago

Describe the feature you'd like The user switching in this app is already much better than many other similar applications. It would be even better if the Jellyfin users switches automatically when the Apple TV user changes.

Additional context Apple provides a class to link the in-app user (they call this a profile) to the user of the Apple TV: https://developer.apple.com/documentation/tvservices/mapping_apple_tv_users_to_app_profiles#overview.

They also presented this at WWDC: https://developer.apple.com/videos/play/wwdc2019/211 at 31:40

acvigue commented 2 years ago

This should already be implemented. I may be able to take a closer look later tonight.

LePips commented 2 years ago

This used to be implemented but is a regression when I did my Session re-factoring. This will actually be a bit of work, adding another field to the StoredUser/User objects that will store the corresponding tvOS user profile, switching users on startup (and error handling if the JF user is signed out), and then being able to select which tvOS user maps to a JF user.

Edit: Or, we can just remember the last JF user that was signed in with the current tvOS user, this seems a lot easier. Can just be done in Defaults with a mapped dictionary [tvOS user : JF user]

acvigue commented 2 years ago

Or, we can just remember the last JF user that was signed in with the current tvOS user, this seems a lot easier. Can just be done in Defaults with a mapped dictionary [tvOS user : JF user]

I think this was actually how I had it implemented earlier, however it makes sense that it was removed when the entire session system was redone.

LePips commented 2 years ago

So I had an attempt on the linked PR with comments as to why this may not work. However, I have been thinking of a "Quick Switch User" little list that can pop up on the settings menu.

We could run the app with the Get Current User entitlement to achieve however I think that would cause more problems than what its worth since all JF users have to be re-logged in per tvOS user.

If somebody would like to take my work and try and fix it (like putting a retry-delay if the tvOS user id is nil or something, idk just something I thought about) that's fine.

jorritolthuis commented 2 years ago

Or, we can just remember the last JF user that was signed in with the current tvOS user, this seems a lot easier. Can just be done in Defaults with a mapped dictionary [tvOS user : JF user]

If this is indeed much easier, this seems like a sensible solution. It's less fancy, but will suffice for pretty much every use case.

Could you explain why this would be easier? It still needs to be notified when the tvOS user switches, it still needs to be unlinked when a JF user logs out (regardless of whether you catch this as an error, or update the mapping/dictionary upon logout), it still needs to handle complicated situations such as when media is playing during a tvOS switch and the new JF user doesn't have access to whatever is playing. I can only see that it saves some work in building the GUI elements for user selection and settings.

We could run the app with the Get Current User entitlement to achieve however I think that would cause more problems than what its worth since all JF users have to be re-logged in per tvOS user.

Are you sure about that? If I check the documentation, it seems like runs-as-current-user indeed requires every JF user to be logged-in for every TV OS user, but I believe get-current-user allows the app to manage JF and tvOS users by itself.

If somebody would like to take my work and try and fix it (like putting a retry-delay if the tvOS user id is nil or something, idk just something I thought about) that's fine.

I could take a look, but given that I have no specific Swiftfin or tvOS experience, this might be a bit too complex as a first project.

LePips commented 2 years ago

your second paragraph

That way is easier just implementation-wise. Instead of dealing with CoreData everything is handled in defaults and by the SessionManager. My attempt includes all of updating on signing out and signing in. You're correct in that switching while watching media is a good case (and the most sensible one) but that also presents difficulties because we would have to send a playback report (actually not that difficult, but would require a lot more work for building a global app state handler that can tell when in playback).

your third paragraph

Sorry yes, I mixed them up. Running the app as runs-as-current-user instead would cause more problems than what its worth.

Edit: thought about "global app state handler" a bit more and we can handle this with just notifications when playback starts and such. Not the cleanest but is doable and easy.

holow29 commented 2 years ago

FYI - Apple has updated this functionality with tvOS 16: https://developer.apple.com/videos/play/wwdc2022/110384/ Mapping profiles is deprecated because system will handle it. All the app needs to do is have runs-as-current-user because then each user will have their login stored in their user keychain individually, as far as I can tell. This means that each user would need to login separately to jellyfin, but I think that is what we want. The above seems more desirable, but there is now also a way to have a user-independent keychain to store login info across users.

LePips commented 2 years ago

We don't use the keychain so that isn't something to worry about. I haven't looked at this for a long time, so I might just go an implement this with runs-as-current-user. I guess in the past we just didn't want that functionality and instead there was single shared set of logins on the Apple TV where Apple TV users would be mapped to a Jellyfin user, which probably would have been the "last used" Jellyfin user.