I'm trying to send NSURLConnection.SendAsynchronousRequest to a URL that requests an authentication.
I'm implementing the method:
func connection(connection:NSURLConnection!, willSendRequestForAuthenticationChallenge challenge:NSURLAuthenticationChallenge!) {
if challenge.previousFailureCount > 1 {
} else {
println("Asking for auth")
let creds = NSURLCredential(user: usernameTextField.text, password: passwordTextField.text, persistence: NSURLCredentialPersistence.None)
challenge.sender.useCredential(creds, forAuthenticationChallenge: challenge)
The method is not being called, also the line is not being printed.
Am i doing everything right?
I'm new to coding with swift, it seems right to me but it just doesn't work...
(new edit) Hmm. rebooted and now it is calling willSendRequestForAuthenticationChallenge is being called. I didn't change any of the code, so Xcode must have gotten in an odd state. If I figure out more, I'll update.
(original post)
Seems to be a problem in Xcode 6 Beta 4. I put my code back in Beta 3 and my willSendRequestForAuthenticationChallenge is being called. I'll run for this as a temp workaround for now.
I did file a radar with Apple on this one.
Related
I'm using ASWebAuthenticationSession authorization for my application.
It works fine before macOS12.4, but occur unresponse's issue.
After "session.start success", Click Cancel or Continue and there is no response.
var session = ASWebAuthenticationSession.init(url: url, callbackURLScheme: "http", completionHandler: completionHandler)
guard let provider = NSApplication.shared.keyWindow!.contentViewController as? FlutterViewController else {
result(FlutterError(code: "FAILED", message: "Failed to aquire root FlutterViewController" , details: nil))
return
}
session.presentationContextProvider = provider
if(!session.start()) {
NSLog("session.start fail");
} else {
NSLog("session.start success");
}
Edit: I just noticed I did not read correctly and missed the fact that this question was for macOS, not iOS. I still hope one of those answers might lead to a solution.
I have noticed 2 things that seem incorrect to me.
The first one is that you need a strong reference for your session. This limitation is only valid for iOS version < 13.0.
This means, the session variable must "outlive" the invoked method it was started in, e.g. setting a session attribute for the whole class.
I cannot see something similar in the code snippet you provided, it looks like a scoped variable to me.
From Apples documentation for this feature:
For iOS apps with a deployment target earlier than iOS 13, your app
must keep a strong reference to the session to prevent the system from
deallocating the session while waiting for authentication to complete.
The second thing is your callback URL scheme seems to be set to https.
The scheme should match your apps bundle ID.
It must be configured in your Info.plist file. Here's an example how to achieve this. It should actually be something like com.company.myappname instead of http. Your authentication provider would also need to redirect to com.company.myappname://someurl to make this work. Please note the :// must not be part of the callback URL scheme, only the part before that.
I've been trying to use the verifyReceipt endpoint to verify in-app purchase transactions with no success.
Here's how I'm doing it.
1. Read the receipt data in iOS (this is copy paste from Apple's documentation):
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
print(receiptData)
let receiptString = receiptData.base64EncodedString(options: [])
// sendReceiptToBackEnd(receiptString)
}
catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
2. In the backend, I followed this advice from Apple:
As a best practice, always call the production URL for verifyReceipt first, and proceed to verify with the sandbox URL if you receive a 21007 status code.
So first I try this (python code):
data = {
'receipt-data': receipt_string, # this is what we get from the frontend
'password': settings.APP_STORE_SHARED_SECRET
}
url = 'https://buy.itunes.apple.com/verifyReceipt'
response = requests.post(url, json=data)
response_data = response.json()
status = response_data['status']
Status here is 21007, which is expected according to the advice above. So then I try the sandbox:
url = 'https://sandbox.itunes.apple.com/verifyReceipt'
response = requests.post(url, json=data)
response_data = response.json()
status = response_data['status']
And I get 21002 - which means there's probably something wrong with what I sent.
Initially I was trying to test this using Xcode locally, but I found out later that verifyReceipt doesn't work with this feature because app's are not signed by the App Store. So I deleted the local configs and set the StoreKit Configuration in scheme back to none, and verified the app is using the App Store Connect as it was picking up any changes I made there in the price.
I'm out of ideas on how to debug this further, so I'm wondering could it be because the App & IAPs are not submitted yet? Currently the app is in the "Prepare for Submission" state, and the IAPs are in the "Ready to Submit" state. Or maybe there is something else I'm missing?
Edit: The answer to my question is "yes, you can." I copied and pasted the json and sent it manually using Postman and it worked fine so something is happening in the backend. I'm leaving the question for reference but if someone recommends deleting please let me know.
I saw your edit, but just as a follow-up code 21002 is a "malformed body" response (or theoretically an Apple server issue, but I've only seen it when mangling the receipt data).
You can see the full list of codes and meanings here:
https://developer.apple.com/documentation/appstorereceipts/status
Incidentally, as you build our your server to process iTunes responses you may find this guide useful for processing the receipt on the server:
https://www.namiml.com/blog/app-store-verify-receipt-definitive-guide
When I try to authenticate access to write to a user's mindful minutes store (health app) from the onboarding in my own app, the authentication page doesn't display (although I did have this working in previous versions of the app). The app however doesn't crash and there is only the following message in the debugger:
Error Domain=com.apple.healthkit Code=3 "Failed to look up source with bundle identifier "com.myorg.myapp"" UserInfo={NSLocalizedDescription=Failed to look up source with bundle identifier "com.myorg.myapp"}
The code I am using to request the authentication is as follows:
let typesToShare = Set([
HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.mindfulSession)!
])
self.healthStore.requestAuthorization(toShare: typesToShare, read: nil) { (_, error) -> Void in
if let error = error {
print("\(error)")
}
DispatchQueue.main.async {
self.performSegue(withIdentifier: "openWalkthroughThree", sender: self)
}
}
I have searched around the internet but can't seem t find anyone with the same issue. I have also checked my entitlements for HealthKit as well as usage description but they both seem to be fine - as I said, I had this working in previous versions of my app.
I would be grateful for any help you could give me in finding a solution to this problem.
Not sure what's going on but simply restarting my device fixed this issue.
Also see: Missing HealthKit Entitlement
I'm building an iOS app using Firebase for the backend and need to use Firebase Callable Cloud Functions. I have everything set up as per docs and functions fire and behave as expected when launched from browser or curl but I cannot get them to fire from my app.
I've set up a test app just using the functions and I cannot get that to fire from iOS app either. Not even a basic hello world. Nothing is getting through.
All of the following has been done:
Firebase side:
Firebase is connected to app successfully
Installed/Initialised the Firebase Functions locally.
Written function code in VSCode trying both Javascript and TypeScript
Successfully deployed to Firebase and can see function in console
Tested function via command line and browser on local server all works as expected
iOS side:
Pod installed Firebase functions
imported Firebase functions into ViewController
Used Firebase SDK to invoke function matching name of function on Firebase - attached to button trigger
And I get nothing... the print statement on the button works but the function doesn't fire and nothing gets logged to Firebase logs.
What am I missing or doing wrong here?
Tried new project with new instance of Firebase.
Copied code directly from examples on Firebase docs and followed everything step by step
FIREBASE CODE
const functions = require('firebase-functions');
const admin = require('firebase-admin')
exports.helloWorld = functions.https.onCall((data, context) => {
const text = data.text;
console.log("Text: " + text);
const uid = context.uid;
console.log("UID: " + uid);
const name = context.name;
console.log("Name: " + name);
console.log('Hello world fucking worked baby!');
return {
message: text
}
});
SWIFT CODE
import UIKit
import FirebaseFunctions
class ViewController: UIViewController {
lazy var functions = Functions.functions()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func fireFunction(_ sender: Any) {
print("Button Fire")
let data = ["text": "hello!"]
functions.httpsCallable("helloWorld").call(data) { (result, error) in
print("Function returned")
if let err = error {
print(err)
}
if let res = result {
print(res)
}
}
}
}
It seems that the Google Cloud Function is working properly if it is being called from a browser. You can also view the LOGs of the Cloud Function. Simply go to the Cloud Functions page and click on your function. Click on the VIEW LOGS button and try calling the URL again, if there is an error with the way Swift calls it, it will be logged there.
I have not worked with iOS Swift very much, but since you are trying to call the function via internet, I am thinking that you might need to give permissions to the App to access the Internet. It looks like the call is never initiated in the Cloud Function, that is why it is not triggered.
I assume that the Cloud Function is an HTTP triggered one. Therefore as a workaround, you can call the function initiating an HTTP request from the App. Again, this won't work though, unless you make sure that your App has the permissions to use the internet.
I implemented Sinch + PushKit + CallKit, everything works fine, but there is one script that does not work correctly. The first user uses the application and removes it from the device's memory, the second user calls for the first time, the first user does not receive the call, if the second user immediately calls the second time, the first user receives a call (later the first user also receives a call). If the first user opens the application (that is, becomes online for the system), the first user will not receive the call again. How can I fix it?
initialization of the sinch client
open func setup() {
guard sinch == nil else { return }
guard let userID = UserRealmManager().getUser()?.id else { return }
sinch = Sinch.client(withApplicationKey: key, applicationSecret: secret, environmentHost: host, userId: userID)
sinch?.delegate = self
sinch?.call().delegate = self
sinch?.setSupportCalling(true)
sinch?.enableManagedPushNotifications()
sinch?.setSupportPushNotifications(true)
sinch?.start()
sinch?.startListeningOnActiveConnection()
}
Update: I also found that if I restart the iPhone then calls through CallKit start to show up in 2-4 minutes, I decided to test it on the famous messangers such as What's app and Telegram and they have exactly the same behavior. Of course, I think it needs to be asked as an additional question.
My devices are iPhone 6 and 7.
This was my mistake, since I initialized SinchManager (this is the manager that manages SINClient) only in MainTabBarController viewDidLoad(), after I began to initialize it in AppDelegate didFinishLaunchingWithOptions, everything works fine.