Why is admob consent form not loading on actual devices? - ios

I am trying to implement Admob for my iOS app. The form loads on the Xcode simulator devices. I am located in the US, but I have used the following code to test that the Consent SDK is working for European users. When I use this with a simulator, the form and ads load.
PACConsentInformation.sharedInstance.debugIdentifiers = ["SPECIFIC_TO_MY_DEVICE"]
PACConsentInformation.sharedInstance.debugGeography = PACDebugGeography.EEA
The form does not load on my physical device with this configuration. The form also did not load when I used testflight to distribute a test version to a test user in the EU. Subsequently, the ads did not load on "European" devices.
When the form should load, I get an error from the below block of code. Also. I get the error WebKitDomain Error 101. My ATS settings are set up in the plist per the Admob documentation.
thisForm.load {(_ error: Error?) -> Void in
if let error = error {
print("Error loading form: \(error.localizedDescription)")
//I am getting the error here.
} else {
thisForm.present(from: self) { (error, userPrefersAdFree) in
print("in present handler")
if let error = error {
// Handle error.
print("error presenting: \(error.localizedDescription)")
} else if userPrefersAdFree {
//TODO: find a way to disable ads
} else {
// Check the user's consent choice.
//let status = PACConsentInformation.sharedInstance.consentStatus
}
}
}
Does anyone know what may be causing these errors with physical devices? I have tried with a real ad id and a test ad id.

Present consent form only if the following equals true
If requestLocationInEEAOrUnknown == true {
//present consent form
}
else {
//do whatever is needed
}

Related

migrating project to comply with google sign in requirements for iOS

I'm trying to get a google sign in button to work with my iOS app, but I'm getting this error here:
Cannot find 'presentingViewController' in scope
This is the code segment:
func handleSignInButton() {
GIDSignIn.sharedInstance.signIn(
with: signInConfig,
presenting: presentingViewController // this is the line with the error,
callback: GIDSignInCallback? = nil) { user, error in
guard let signInUser = user else {
// Inspect error
return
}
// If sign in succeeded, display the app's main content View.
}
}
I've been told I need to migrate the way I am signing in and I found this here:
https://developers.google.com/identity/sign-in/ios/quick-migration-guide
but I'm confused about this part here:
Manually connect GIDSignInButton to a method that calls signInWithConfiguration:presentingViewController:callback: using an IBAction or similar.
Can someone show me how to do this properly? I'm a iOS novice :)
Thanks!

Authenticating the user with biometrics causing application to crash

So i'm following the books in terms of authenticating a user using biometrics. Below is some code i've wrote in a custom class called biometrics manager.
func authenticateUser(completion: #escaping (_ result: BiometricsStatus) -> Void) {
DispatchQueue.main.async {
guard self.deviceHasBiometricCapabilities() else { completion(.fail(error: .touchIDNotAvailable)); return }
let authMethod = self.biometricType() == .faceID ? "Face ID" : "Touch ID"
let loginMessage = "\(authMethod) to sign in"
self.context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: loginMessage) { success, evaluateError in
if success {
completion(.success)
return
}
if let error = evaluateError {
completion(.fail(error: self.getBiometricsError(from: error)))
return
}
}
}
}
I've debugged my application and it seems to be causing a crash on the evaluate policy line, i've enabled exception breakpoints to try and catch the crash but i'm receiving nothing at all in the console logs. The only thing that i seem to be getting in the console is the following.
Message from debugger: Terminated due to signal 9
Which isn't super helpful any possible pointers or ideas that may be causing this crash to occur at all?
You need to add the NSFaceIDUsageDescription key to your info.plist
From https://developer.apple.com/documentation/localauthentication/lacontext
Important
Include the NSFaceIDUsageDescription key in your app’s Info.plist file if your app allows biometric authentication. Otherwise, authorization requests may fail.

Why evaluatePolicy fails only once if TouchID is turn off for iPhone Unlock

I want to use TouchID in my app and I've found some weird behaviour. So in general when TouchID alert is shown it and user try to authenticate with fingerprint canEvaluatePolicy will fail only after 3 attempts but if user go to Settings>Touch ID & Passcode and turn off "use touch id for: iPhone Unlock" canEvaluatePolicy will fail after first attempt with error message "Biometry is disabled for unlock.". Does anyone know is it a bug or it is by design.
Also looks like it happens only on iOS 11.
Here is code that i use for TouchID configuration
var error: NSError?
context.localizedFallbackTitle = "fallback title"
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in
DispatchQueue.main.async {
if success {
// success case
}
else {
// error handling
}
}
}
}
else {
// error handling
}

Game Center achievements not supported

I am having some problems trying to implement game center achievements into an iOS game. The game already has the player authentication and leaderboards setup and they are working fine. The first error I get is when using this method:
GKAchievementDescription.loadAchievementDescriptionsWithCompletionHandler
It gives me an error which states two things:
"The requested operation could not be completed due to an error communicating with the server."
"App does not support achievements."
Five achievements have been added to iTunes connect so I don't no why it says it doesn't support them. The other issues are when I use this method:
GKAchievement.reportAchievements
When this is called the error in the completion handler is nil, but it returns "no bundle for bundleID: (null)". The achievement banner doesn't show and there is no achievements tab in the game centre view.
The app was recently transferred to another developer but he then wanted some extra features added to it, so I'm using a provisioning profile and developer certificate provided by him so I can test game center and in app purchases properly. It seems like the problem I'm having is relating to the transfer?
So my question is what could be the problem causing the game to 'not support achievements'?
Any help would be much appreciated,
thank you.
Your question is a bit vague, how are those two methods looking exactly in your code. Its hard to help with two lines of a function
You load code should look something like this
/// Load achievements
func loadAchievements(){
print("Loading submitted achievements")
GKAchievement.loadAchievementsWithCompletionHandler( { (achievements, error:NSError?) -> Void in
guard error == nil else {
print("Error loading achievements progress: \(error)")
return
}
guard let validAchievements = achievements else { return }
for achievement in validAchievements {
print("Name: \(achievement.identifier)")
print("Percentage: \(achievement.percentComplete)")
print("Date: \(achievement.lastReportedDate)")
self.achievementsDict.updateValue(achievement, forKey: achievement.identifier!)
}
})
}
You report code should look something like this
/// Save achievement progress
func reportAchievementProgress(percent: Double, achievementID: String) {
guard self.localPlayer.authenticated else { return }
let achievement = self.checkAchievement(achievementID) as GKAchievement? //
if achievement != nil {
achievement!.percentComplete = percent
achievement!.showsCompletionBanner = true
GKAchievement.reportAchievements([achievement!], withCompletionHandler: { (error:NSError?) -> Void in
guard error == nil else {
print(error)
return
}
print("Reported achievement: \(achievementID)) to: \(percent) %")
})
}
}
/// Check achievement
private func checkAchievement(achievementID: String) -> GKAchievement {
var achievement = self.achievementsDict[achievementID]
if achievement == nil {
print("Achievement with no previous progress, saving...")
achievement = GKAchievement(identifier: achievementID)
self.achievementsDict.updateValue(achievement!, forKey: achievement!.identifier!)
}
return achievement!
}
achievementsDict is a dictionary where you cache your achievements.
var achievementsDict = [String: GKAchievement]()
Does this help?

Getting single Tweet with TwitterKit/Fabric authentication failure

I'm trying to retrieve a single tweet and show it in my application via the TWTRTweetView provided in the TwitterKit. I've followed this Fabric guide and ended up with following code.
import UIKit
import TwitterKit
class SingleTweetViewController: UIViewController{
#IBOutlet weak var plainView: UIView!
override func viewDidLoad(){
super.viewDidLoad()
Twitter.sharedInstance().logInGuestWithCompletion { session, error in
if let validSession = session {
Twitter.sharedInstance().APIClient.loadTweetWithID("4831830029115392") { tweet, error in
if let t = tweet {
let tweetView = TWTRTweetView(tweet: tweet)
tweetView.showActionButtons = true
self.plainView.addSubview(tweetView)
} else {
println("Failed to load Tweet: \(error?.localizedDescription)")
}
}
} else {
println("Unable to login as guest: \(error.localizedDescription)")
println(error?.localizedFailureReason)
}
}
}
The code generates these two errors due to authentication failure.
Unable to login as guest: Request failed: forbidden (403)
Optional("Twitter API error : Unable to verify your credentials (code 99)")
It is worth mentioning that the app successfully signs in to Twitter via the login button added following this guide. Does anyone have a clue how this error could be fixed? Am I missing some code here or is the issue related to Fabric?
You have to initialize Fabric before trying to use it which is what you're doing in your example code.
For the initialization, follow instructions from the Fabric documentation site. In essence, you have add the following lines to your app delegate (in addition to importing TwitterKit):
Twitter.sharedInstance().startWithConsumerKey("your_key", consumerSecret: "your_secret")
Fabric.with([Twitter.sharedInstance()])
Then copy and paste you're consumer key and secret from fabric.io. Fabric should automatically generate these for you.
I solved the problem using Fabric applications built in option "View tweet in application" found in the same menu as the "Add login button button" option. The Fabric application then inserts proper authentication keys into the Info.plist file. The code provided by Fabric application seems to do the same thing as the code given on Fabric docs but the result differs depending on which one you use. The two code samples look like this:
Code from Fabric docs:
Twitter.sharedInstance().logInGuestWithCompletion { session, error in
if let validSession = session {
Twitter.sharedInstance().APIClient.loadTweetWithID("20") { tweet, error in
if let t = tweet {
self.tweetView.configureWithTweet(t)
} else {
println("Failed to load Tweet: \(error.localizedDescription)")
}
}
} else {
println("Unable to login as guest: \(error.localizedDescription)")
}
}
Code from Fabric application:
Twitter.sharedInstance().logInGuestWithCompletion { (session, error) in
Twitter.sharedInstance().APIClient.loadTweetWithID("20") { (tweet, error) in
self.view.addSubview(TWTRTweetView(tweet: tweet))
}
}
Running the first code will give an authentication error while the second one will load a tweet without issues. The if-statement if let validSession = session returns a false and an authentication error occurs. I couldn't find what the validSession is exactly but it probably compares two different sets of keys or something similar.

Resources