Issues loading Images Xcode Swift 5 (SDWebImage/Backblaze used) - sdwebimage

i am encountering a weird issue.
Short version
We have an app in the appstore for multiple months now with a photo feed. We have plenty of users (99,9% in Europe, mostly Central Europe).
using SDwebImage for image downloading
Backblaze as cloud storage
The issue:
On our end there is no issue. And none of our users encounter issues when showing the images.
However when Apple reviews our app, they are not able to download images at all (the exact same which work for us and all users).
What we tested
SDWebImage was shortly replaced with Kingfisher -> same result
We tried to reproduce the issue but weren't able: We set the location of our simulator to all possible locations + changed languages, clean rebuild etc. Never encountered the issue.
We tried around with AllowArbitrary loads but still won't work for our Apple reviewer.
Code
postImageView.sd_imageIndicator?.startAnimatingIndicator()
let photoUrl = URL(string: photoUrlString)
postImageView.backgroundColor = .systemGray3
postImageView.sd_imageIndicator = SDWebImageActivityIndicator.grayLarge
SDWebImageDownloader.shared.config.downloadTimeout = 40
postImageView.sd_setImage(with: photoUrl, placeholderImage: nil, options: .allowInvalidSSLCertificates) { (image, err, sd, url) in
self.postImageView.sd_imageIndicator = nil
self.postImageView.sd_imageIndicator?.stopAnimatingIndicator()
if err != nil {
self.postImageView.image = UIImage(named: "placeholder-image")
Ref().databaseProblems.child("IMAGE_IOS").child(UUID().uuidString).setValue("\(err.debugDescription) + \(err?.localizedDescription ?? "")")
}
}
the error codes
Optional(Error Domain=NSURLErrorDomain Code=-1001 \"The request timed out.\" UserInfo={_kCFStreamErrorCodeKey=60, NSUnderlyingError=0x28334f120 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 \"(null)\" UserInfo={_kCFStreamErrorCodeKey=60, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <49574986-C917-4980-ABC7-6A9E9EBD6892>.<3>, _NSURLErrorRelatedURLSessionTaskErrorKey=(\n \"LocalDataTask <49574986-C917-4980-ABC7-6A9E9EBD6892>.<3>\"\n), NSLocalizedDescription=The request timed out., NSErrorFailingURLStringKey=https://f000.backblazeb2.com/file/Images/-MVVvWz3rlPQw5J5_Ah_, NSErrorFailingURLKey=https://f000.backblazeb2.com/file/Images/-MVVvWz3rlPQw5J5_Ah_, _kCFStreamErrorDomainKey=1}) + The request timed out."
"Optional(Error Domain=SDWebImageErrorDomain Code=2002 \"Operation cancelled by user during sending the request\" UserInfo={NSLocalizedDescription=Operation cancelled by user during sending the request}) + Operation cancelled by user during sending the request"
"Optional(Error Domain=NSURLErrorDomain Code=-1022 \"The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.\" UserInfo={NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection., NSErrorFailingURLStringKey=http://f000.backblazeb2.com/file/Images/-MVTKiJrFDOldW94d0cO, NSErrorFailingURLKey=http://f000.backblazeb2.com/file/Images/-MVTKiJrFDOldW94d0cO, _NSURLErrorRelatedURLSessionTaskErrorKey=(\n \"LocalDataTask <F3ADD147-226D-48EF-8B3A-2C61EF2887FE>.<2>\"\n), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <F3ADD147-226D-48EF-8B3A-2C61EF2887FE>.<2>, NSUnderlyingError=0x60400036d550 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 \"(null)\"}}) + The resource could not be loaded because the App Transport Security policy requires the use of a secure connection."
info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>https://f000.backblazeb2.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
Any idea/suggestion?

Related

Firebase Google SignIn failed - "Audience Mismatch"

I have implemented Google sign in via Firebase and followed proper documentation: https://firebase.google.com/docs/auth/ios/firebaseui
I am using,
- FirebaseUI/Auth (8.5.1):
- Firebase/Auth (~> 6.0)
- GoogleUtilities/UserDefaults
- FirebaseUI/Google (8.5.1):
- FirebaseUI/Auth
- GoogleSignIn (~> 5.0)
COCOAPODS: 1.9.3
XCode - 12
So, my Appdelegate.swift would contain following code in didFinishLaunchingWithOptions...
FirebaseApp.configure()
And presenting SignIn UI when user presses a special button on Login view controller using below code,
if let authController = authUI?.authViewController() {
self.authController = authController
self.present(authController, animated: true, completion: nil)
}
LoginViewController.swift would have following code into viewDidload()
authUI?.delegate = self
let providers: [FUIAuthProvider] = [
FUIGoogleAuth()
]
authUI?.providers = providers
where authUI is declared as property for LoginViewController => let authUI = FUIAuth.defaultAuthUI()
I have only added Google SignIn for now so only one provider added here.
Now when my SignIn Auth UI is presented, Google SignIn button is shown and I am able to log into my Google account but when didSignInWith authDataResult is executed from FUIAuthDelegate, I get to know I am receiving an error post successful Google Account Login.
Error Domain=FUIAuthErrorDomain Code=2 "(null)" UserInfo={FUIAuthErrorUserInfoProviderIDKey=google.com, NSUnderlyingError=0x600000a08720 {Error Domain=org.openid.appauth.general Code=-15 "Audience mismatch" UserInfo={NSLocalizedDescription=Audience mismatch}}}
Is there anything I am missing?
I have already setup URL schema into info.plist and not getting any clue on how this kind of error is being generated.
Further as an update to #frank-van-puffelen,
I have confirmed proper info.plist is added or not.
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>CLIENT_ID</key>
<string>847792004435-gdisqis038je5q8rr1on4ti7df09nvht.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.847792004435-gdisqis038je5q8rr1on4ti7df09nvht</string>
<key>API_KEY</key>
<string>AIzaSyDRrYM2h1wOEdKHZtOM-M904oBwrXnaO3E</string>
<key>GCM_SENDER_ID</key>
<string>847792004435</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.Speare.StashAlpha</string>
<key>PROJECT_ID</key>
<string>stash-demo-11379</string>
<key>STORAGE_BUCKET</key>
<string>stash-demo-11379.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:847792004435:ios:867e5fb8113b83b48f55a6</string>
<key>DATABASE_URL</key>
<string>https://stash-demo-11379.firebaseio.com</string>
</dict>
</plist>
Screenshot of project which is targeted for login,
We can clearly check here Project ID matches in info.plist as well as on Sign In screen.
Now in Firebase console, if we check, project ID matches and below is info.plist download button from where I can take latest info.plist.
Let me know if there is anything we can confirm info.plist does not match with target project.
This error message usually means that you're trying to sign in to a different project than what the token was minted for. So you might want to check if you have the info.plist for the correct project, and that you're set up you OAuth sign in against that same project.

Open link in Safari from UIWebView

What i'm trying to do is open a website in Safari, through having the user click on a link that is displayed in my UIWebView.
I started by reading through the question/answers on:
Open specific link in Safari from UIWebView
Afterwhich I implemented the following:
class HomeInfoView: UIViewController, UIWebViewDelegate{
override func viewDidLoad() {
super.viewDidLoad()
let localfilePath = NSBundle.mainBundle().URLForResource("homeInfo", withExtension: "html");
let myRequest = NSURLRequest(URL: localfilePath!);
WebViewer.loadRequest(myRequest);
WebViewer.scrollView.bounces = false
}
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if let url = request.URL where navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(url)
return false
}
return true
}
However when trying to use the link I still get an error
"App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file."
I think I'm 90% of the way there, yet I'm not sure how to edit my .plist to allow the exception. Or if there is something else that I've missed.
(I would've added this as a comment to the original post but my rank isn't high enough yet)
You will need to either grant permission to that specific domain in your info.plist :
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>testdomain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>
This info in your plist basically sets up an exception in your app. It allows you to access the testdomain.com domain (insert whatever domain you are trying to access). It lets you access all of the subdomains and then sets a minimum TLS version to help ensure the site you are connecting to is the one you want.
Or you you can simply allow access to all http websites, which is not recommended.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
This isn't recommended because it allows your app to access any http:// domain, which can be a security problem because it can make your app vulnerable to man-in-the-middle attacks.
Check out Apple's documentation for more info on this.
https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33

Facebook Account Kit SDK gives invalid OAuth 2.0 error

I have integrated Account kit sdk in to my project.
I created the application on facebook development dashboard, enabled Account Kit on it. Got app-id and client access token.
I added it into info.plist file. I am getting this error:
[AccountKit][Error]: Invalid OAuth 2.0 Access Token
2016-05-31 02:41:32.191 Chat[2919:563260] [AccountKit][Error]:
Persisting App Events due to error:
Error Domain=com.facebook.accountkit:Error Code=200 "(null)"
UserInfo={com.facebook.accountkit:ErrorDeveloperMessageKey=Invalid OAuth access token., NSUnderlyingError=0x147596a30
{Error Domain=com.facebook.accountkit:ServerError Code=190 "(null)" UserInfo={com.facebook.accountkit:ErrorDeveloperMessageKey=Invalid OAuth access token.}}}
Please need help. Thanks
Make sure you have the correct settings in info.plist.
I had a similar problem and in my case it was missing a key FacebookAppID
<key>FacebookAppID</key>
<string>{your-app-id}</string>
<key>AccountKitClientToken</key>
<string>{your-account-kit-client-token}</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>ak{your-app-id}</string>
</array>
</dict>
</array>
Make sure that initialization response type of AKFAccountKit matches with your application dashboard configuration.
It can be:
accountKit = [[AKFAccountKit alloc] initWithResponseType:AKFResponseTypeAccessToken];
or
accountKit = [[AKFAccountKit alloc]initWithResponseType:AKFResponseTypeAuthorizationCode];
This might be an issue with your configuration. You can file a bug report with Facebook here including your token information: https://developers.facebook.com/bugs/
I got this error when I had copied the wrong AccountKitClientToken into the Info.plist. Got the right one in there and everything is working now!
You can add your client token using AKFSettings.setClientToken("MY TOKEN") and make sure to import AccountKit at the top of the file where you call this.

canOpenURL: failed for URL: "instagram://app" - error: "(null)

I get this error:
-canOpenURL: failed for URL: "instagram://app" - error: "(null)"
This is the code I use:
let instagramURL = NSURL(string: "instagram://app")!
if (UIApplication.sharedApplication().canOpenURL(instagramURL)) {
//some code
}
I added LSApplicationQueriesSchemes to my info.plist file
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
</array>
And it seems to "recognise" the instagram scheme, cause when I use something else like "instagraam" I get a different error message (which makes sense):
-canOpenURL: failed for URL: "instagraam://app" - error: "This app is not allowed to query for scheme instagraam"
Am I missing something obvious?
As pointed out in the comments - this is in fact a duplicate of this.
On a real device it works, it's just weird output of the simulator.

Load internet url to Webview

I'm working on a project where I want to load a internet URL to my UIWebView
I've managed to load a locally stored html file like this:
if let url = NSBundle.mainBundle().URLForResource("index", withExtension: "html") {
webView.loadRequest(NSURLRequest(URL: url))
}
So based on that I tried doing it like this:
if let url = NSURL(string: "http://google.com") {
webView.loadRequest(NSURLRequest(URL: url))
}
But that didn't seem to work.
Apple introduced App Transport Security with iOS9. That is a new security feature that enforces certain security practices when working with web requests. For example it won't allow to send requests via HTTP, because it only allows HTTPS requests. The good news is that you can override these security requirements by adding this to your project's Info.plist file:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Just be aware that this circumvents ALL security requirements that came with ATS.
You should use this in production only if there really is no other way. If you only access 1 non HTTP url you can disable ATS for that 1 domain only:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourdomain.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
As joern says,the security update requires all requests to be via HTTPS if you don't want to override it.
So the basic quick fix to this would be just changing the link to https.
So something like this:
if let url = NSURL(string: "https://google.com") {
webView.loadRequest(NSURLRequest(URL: url))
}
Try below code :
let url = "http://google.com"
let requestURL = NSURL(string:url)
let request = NSURLRequest(URL: requestURL!)
WebView.loadRequest(request)