OneSignal / OneSignal-iOS-SDK

OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your native iOS app with OneSignal. https://onesignal.com
Other
496 stars 263 forks source link

[Bug]: Resuming an NSURLSessionTask with nil URL #1325

Open rhdez opened 1 year ago

rhdez commented 1 year ago

What happened?

This happens with iOS 16 but in iOS 17. After OneSignal.login(externalId) with an existing externalId, the session never get updated with the subscription because the OneSignalUser.OSRequestFetchUser fails with this error:

2023-10-25 14:31:05.426016-0600 [77089:2025889] [API] API MISUSE: Resuming an NSURLSessionTask with nil URL.
2023-10-25 14:31:05.427609-0600 [77089:2026620] Task <A112B480-D0F6-4CB0-9A38-DD90D1422A57>.<8> finished with error [-1002] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSUnderlyingError=0x600001568fc0 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <A112B480-D0F6-4CB0-9A38-DD90D1422A57>.<8>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <A112B480-D0F6-4CB0-9A38-DD90D1422A57>.<8>"
), NSLocalizedDescription=unsupported URL}
2023-10-25 14:31:05.427850-0600 [77089:2026620] DEBUG: Re-scheduling request (OneSignalUser.OSRequestFetchUser) to be re-attempted in 15.000 seconds due to failed HTTP request with status code 0

Before this happen, the login tried to POST the externalId getting an error: DEBUG: executeIdentifyUserRequest returned error code user-2. Now handling user-2 error response... switch to this user. Right after this, the above error appears.

With iOS 17, right after the user-2 error, the OneSignalUser.OSRequestFetchUser returns a success response with the session data.

NOTE the externalId is something like: auth0|12345676

Steps to reproduce?

1. Create a session
2. Login with an `externalId`
3. Add some tags
3. Logout
4. Login again with the same `externalId`
5. Tags never get loaded because the session couldn't be retrieved from the user with the `externalId`

What did you expect to happen?

To retrieve the tags from the user with the externalId

OneSignal iOS SDK version

Release 5.0.1 and 5.0.2

iOS version

16

Specific iOS version

iOS 16

Relevant log output

2023-10-25 14:31:05.426016-0600 [77089:2025889] [API] API MISUSE: Resuming an NSURLSessionTask with nil URL.
2023-10-25 14:31:05.427609-0600 [77089:2026620] Task <A112B480-D0F6-4CB0-9A38-DD90D1422A57>.<8> finished with error [-1002] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSUnderlyingError=0x600001568fc0 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <A112B480-D0F6-4CB0-9A38-DD90D1422A57>.<8>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <A112B480-D0F6-4CB0-9A38-DD90D1422A57>.<8>"
), NSLocalizedDescription=unsupported URL}
2023-10-25 14:31:05.427850-0600 [77089:2026620] DEBUG: Re-scheduling request (OneSignalUser.OSRequestFetchUser) to be re-attempted in 15.000 seconds due to failed HTTP request with status code 0


### Code of Conduct

- [X] I agree to follow this project's Code of Conduct

<!-- probot = {"onesignal-probot":{"response_time_in_business_days":1}} -->
rhdez commented 1 year ago

Seems to be related to the externalId special character. In my case, replacing the | with %7C solved the issue.

rhdez commented 1 year ago

Quote by Apple docs:

Important For apps linked on or after iOS 17 and aligned OS versions, URL parsing has updated from the obsolete RFC 1738/1808 parsing to the same RFC 3986 parsing as URLComponents. This unifies the parsing behaviors of the URL and URLComponents APIs. Now, URL automatically percent- and IDNA-encodes invalid characters to help create a valid URL.

https://developer.apple.com/documentation/foundation/url/3126806-init

So this is definitively a bug. It seems that the SDK is not percent encoding the externalId when it creates the GET URL.

https://api.onesignal.com/apps/[APP_ID]/users/by/external_id/auth0|1234asd1234

And the above string is not a valid URL because it includes the special char: | and it is not escaped

For swift, this could be solved by calling this method:

addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
emawby commented 1 year ago

@rhdez Thank you for reporting and for the in depth investigation! We will work on a fix for this. To clarify iOS 17 allows this special character in the url but iOS 16 does not?

rhdez commented 1 year ago

@emawby That is right. As the Apple documentation say for iOS 17:

Now, URL automatically percent- and IDNA-encodes invalid characters to help create a valid URL

But that was not the default behavior for iOS 16 and below, so I understand this as an SDK bug.

Thank you for your reply. Glad to help!

emawby commented 1 year ago

Agreed thank you for the update