Got an "configurationError" when sending a transaction in Xcode - ios

When I try to send a transaction on the Aion network, I keep getting the "configurationError". I am using Xcode to create my IOS dApp.
The code i have to send a transaction is:
#IBAction func sendTxButton(_ sender: Any) {
//deleted my address and pk
let address = "0x0"
let privateKey = "0x0"
let nonce = BigInt.init(3)
let to = "0xa0d969df9232b45239b577c3790887081b5a22ffd5a46a8d82584ee560485624"
let value = BigInt.init(10000000)
let nrgPrice = BigInt.init(10000000000)
let nrg = BigInt.init(21000)
var txParams = [AnyHashable: Any]()
txParams["nonce"] = HexStringUtil.prependZeroX(hex: nonce.toString(radix: 16))
txParams["to"] = to
txParams["data"] = ""
txParams["value"] = HexStringUtil.prependZeroX(hex: value.toString(radix: 16))
txParams["nrgPrice"] = HexStringUtil.prependZeroX(hex: nrgPrice.toString(radix: 16))
txParams["nrg"] = HexStringUtil.prependZeroX(hex: nrg.toString(radix: 16))
do {
let importWallet = try PocketAion.importWallet(privateKey: privateKey, subnetwork: "32", address: address, data: nil)
try PocketAion.eth.sendTransaction(wallet: importWallet, nonce: nonce, to: to, data: "", value: value, nrgPrice: nrgPrice, nrg: nrg, handler: { (result, error) in
if error != nil {
print(error!)
return
} else {
print("the hash:", result!)
}
})
} catch{
print(error)
}
}
I have met all of the requirements on sending a transaction, but cant figure out what is wrong.(this is for sending test tokens on the Aion test net "32").

check your AppDelegates class. make sure you have added "configuration" and point it to the right URL and under the application function you make sure you have the configuration is set to "self".
class AppDelegate: UIResponder, UIApplicationDelegate, Configuration {
public var nodeURL: URL{
get {
return URL.init(string: "https://aion.pokt.network")!
}
}
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
PocketAion.shared.setConfiguration(config: self)
return true
}

Related

Swift 5 store event until all of the app has initialised

Im working on an Ionic/Capacitor native plugin in Swift
I am trying to integrate OneSignal push notification service, my code below works just fine if the app is in the foreground and a user clicks the notification, however if the app is started from clicking a notification my events dont fire, I figure this is because the AppDelegate.swift loads before Capacitor/Ionic and when my NotificationCenter.default.post gets fired the data doesnt reach my plugin.
I guess I want to know if there is any way in Swift to store this post data until all parts of the app have loaded and initialised i.e Capacitor/Ionics webview
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let notificationOpenedBlock: OSHandleNotificationActionBlock = { result in
// This block gets called when the user reacts to a notification received
let payload: OSNotificationPayload = result!.notification.payload
var fullMessage = payload.body
let nc = NotificationCenter.default
nc.post(name: Notification.Name("TestingEvents"), object: nil)
if payload.additionalData != nil {
if payload.title != nil {
let messageTitle = payload.title
print("Message Title = \(messageTitle!)")
}
let additionalData = payload.additionalData
if additionalData?["actionSelected"] != nil {
fullMessage = fullMessage! + "\nPressed ButtonID: \(additionalData!["actionSelected"])"
}
}
}
return true
}
MyPlugin.swift
public override func load() {
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(handleSignal), name: Notification.Name("TestingEvents"), object: nil)
}
#objc func handleSignal() {
self.bridge.triggerWindowJSEvent(eventName: "myCustomEvent")
self.notifyListeners("myPluginEvent", data: [:])
}
and my app.component.ts
window.addEventListener('myCustomEvent', () => {
alert("myCustomEvent ")
});
Plugins.myPlugin.addListener("myPluginEvent", () => {
alert("myPluginEvent ")
});
this is a logical problem. what you can do here is save the notificaiton data (OSNotificationPayload) in an object/dictionary/array you receive in didFinishLaunchingWithOptions and add an observer "HandleNotificaionAfterPluginSetup" to appdelegate.
For this observer, you can trigger a post notification from your plugin once it is initialized and have everything ready to handle notificaitons. once you are all set in your plugin and have triggered the notificaion that code can execute in the notificaion handler you just setup which willl execute the code
if payload.title != nil {
let messageTitle = payload.title
print("Message Title = \(messageTitle!)")
}
let additionalData = payload.additionalData
if additionalData?["actionSelected"] != nil {
fullMessage = fullMessage! + "\nPressed ButtonID: \(additionalData!["actionSelected"])"
}
}```

AVSystemController_SystemVolumeDidChangeNotification not giving callback for the first time

I want to check if both the volume buttons are working fine. So I set the observer AVSystemController_SystemVolumeDidChangeNotification to check that.
NotificationCenter.default.addObserver(self, selector: #selector(volumeCallback(notification:)), name: NSNotification.Name("AVSystemController_SystemVolumeDidChangeNotification"), object: nil)
Given is volumeCallback method:
#objc private func volumeCallback(notification: NSNotification) {
// check if app is in forground
guard UIApplication.shared.applicationState == .active else {
return
}
//get volume level
if let userInfo = notification.userInfo {
if let volumeChangeType = userInfo["AVSystemController_AudioVolumeChangeReasonNotificationParameter"] as? String {
if volumeChangeType == "ExplicitVolumeChange" {
print("value changed")
let level = userInfo["AVSystemController_AudioVolumeNotificationParameter"] as? Float
guard let volLevel = level else {
return
}
// my work here
}
}
}
}
Now the problem is, I am not getting callback in volumeCallback for the first installation of the app. The weird thing is, this method is being called when the app is in background, but not being called in foreground.
I am using iPhone 5s (iOS 10.3.3).
I don't understand what is the problem in this code. Any help will be appreciated.
This can be easily done with key-value observer as AVAudioSession provides outputVolume property. Check here.
You can just add observer on this property and get callbacks.
Here's a simple way of doing this in Swift 5:
// Audio session object
private let session = AVAudioSession.sharedInstance()
// Observer
private var progressObserver: NSKeyValueObservation!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
try session.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("cannot activate session")
}
progressObserver = session.observe(\.outputVolume) { [weak self] (session, value) in
print(session.outputVolume)
}
return true
}

Spotify token swap : unsupported URL error

I'm trying to implement the token swap and refresh for the Spotify sdk. I'm using the Heroku app as a server. Here is my code.
In my Sign-in view controller:
var auth = SPTAuth.defaultInstance()!
var session: SPTSession!
var player: SPTAudioStreamingController?
SPTAuth.defaultInstance().clientID = "********************************"
SPTAuth.defaultInstance().redirectURL = URL(string: "viraj-project2://callback" )
SPTAuth.defaultInstance().tokenSwapURL = URL(string: "https://viraj-project2.herokuapp.com/v1/swap")
SPTAuth.defaultInstance().tokenRefreshURL = URL(string: "https://viraj-project2.herokuapp.com/v1/refresh")
SPTAuth.defaultInstance().requestedScopes = [SPTAuthStreamingScope, SPTAuthPlaylistReadPrivateScope, SPTAuthPlaylistModifyPublicScope, SPTAuthPlaylistModifyPrivateScope, SPTAuthUserLibraryReadScope, SPTAuthUserLibraryModifyScope]
loginUrl = SPTAuth.defaultInstance().spotifyWebAuthenticationURL()
#IBAction func signIn(_ sender: Any) {
self.performSegue(withIdentifier: "toNewsFeed", sender: self)
if SPTAuth.supportsApplicationAuthentication() {
UIApplication.shared.open(loginUrl!, options: [:], completionHandler: nil)
} else {
if UIApplication.shared.openURL(loginUrl!) {
if auth.canHandle(auth.redirectURL) {
// To do - build in error handling
}
}
}
}
and in my AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate{
var window: UIWindow?
var auth = SPTAuth()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
auth.redirectURL = URL(string: "viraj-project2")
auth.sessionUserDefaultsKey = "current session"
// Override point for customization after application launch.
return true
}
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
// 2- check if app can handle redirect URL
if auth.canHandle(auth.redirectURL) {
// 3 - handle callback in closure
print (url)
auth.handleAuthCallback(withTriggeredAuthURL: url, callback: { (error, session) in
// 4- handle error
if error != nil {
print(error)
print("error!")
}
NotificationCenter.default.post(name: Notification.Name(rawValue: "loggedinperformsegue"), object: nil)
// 5- Add session to User Defaults
let userDefaults = UserDefaults.standard
let sessionData = NSKeyedArchiver.archivedData(withRootObject: session!)
userDefaults.set(sessionData, forKey: "SpotifySession")
userDefaults.synchronize()
// 6 - Tell notification center login is successful
NotificationCenter.default.post(name: Notification.Name(rawValue: "loginSuccessfull"), object: nil)
})
return true
}
return false
}
The authentication works fine without adding the swap and refresh URLs. But whenever I run it with the two URLS added to the SPTAuth.defaultInstance() I get a unsupported URL error like so:
viraj-project2://callback/?code=AQDhKLE9s5GQGITEn**********5_y9aKZM6_nSlzA
2018-09-14 16:55:08.258063-0400 Project2[17606:3197471] NSURLConnection finished with error - code -1002
Optional(Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL, NSUnderlyingError=0x109385130 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL}}})
error!
Can someone help?
Update on further digging:
When I include add the tokenSwapURL and tokenRefreshURL to my default instance the loginUrl formed looks like so
"https://accounts.spotify.com/authorize?nolinks=true&nosignup=true&response_type=code&scope=streaming%20playlist-read-private%20playlist-modify-public%20playlist-modify-private%20user-library-read%20user-library-modify&utm_source=spotify-sdk&utm_medium=ios-sdk&utm_campaign=ios-sdk&redirect_uri=viraj-project2%3A%2F%2Fcallback&show_dialog=true&client_id=****************"
The response type is "code" which as per the documentation is the right one according to Authorization Flow. But this is what returns the unsupported URL error.
Without the swap and refresh URLs the loginURL looks the same except that the response_type says "token". And this works fine. Is that right though? Doesn't response_type = token mean implicit grant flow?
https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow

Native AVPlayerViewController called from JavaScript causing autolayout modification from background thread

I am building a TVML/TVJS Apple TV app, but i need to be able to get some native functionality with the player, so I am using evaluateAppJavaScriptInContext to create a JavaScript function that will push a custom view controller to the screen when called. The problem is that it causes a warning in the console:
This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release.
The code looks like this:
import TVMLKit
import AVKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDelegate {
var window: UIWindow?
var appController: TVApplicationController?
var workoutViewController = WorkoutViewController()
static let TVBaseURL = "http://localhost:3000/"
static let TVBootURL = "\(AppDelegate.TVBaseURL)assets/tv.js"
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
// 1
let appControllerContext = TVApplicationControllerContext()
// 2
guard let javaScriptURL = NSURL(string: AppDelegate.TVBootURL) else {
fatalError("unable to create NSURL")
}
appControllerContext.javaScriptApplicationURL = javaScriptURL
appControllerContext.launchOptions["BASEURL"] = AppDelegate.TVBaseURL
// 3
appController = TVApplicationController(context: appControllerContext, window: window, delegate: self)
do {
guard let audioURL = NSURL(string: self.workoutViewController.audioURL) else {
fatalError("unable to create NSURL")
}
let audioPlayer = try AVAudioPlayer(contentsOfURL: audioURL)
if (audioPlayer.prepareToPlay()) {
audioPlayer.play()
}
} catch {
print("Error: \(error)")
}
return true
}
func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext) {
let presentWorkoutViewController : #convention(block) (String) -> Void = { (string : String) -> Void in
self.workoutViewController.jsonString = string
// dispatch_async(dispatch_get_main_queue(), {
self.appController?.navigationController.pushViewController(self.workoutViewController, animated: true)
// })
}
jsContext.setObject(unsafeBitCast(presentWorkoutViewController, AnyObject.self), forKeyedSubscript: "presentWorkoutViewController")
}
}
I tried to wrap it in a dispatch_async and that fixes the error, but when i try to push the native view controller back in view, it still contains its old content, and not the new content that i am trying to display.
That looked like this:
dispatch_async(dispatch_get_main_queue(), {
self.appController?.navigationController.pushViewController(self.workoutViewController, animated: true)
})
Thanks in advance!

Notifications with Swift 2 and Cloudkit

I am making a "texting app" you can call it and it uses cloudkit and I have been looking everywhere to add notifications that work with cloudkit... Would someone be able to tell me the code to add push notifications for cloudkit in detail because I am very lost... Also I wan't the notifications to go to different "texting rooms" (in cloudkit it would be record types...) For instance I have one record type called "text" and another one called "text 2" I don't want notifications from "text" to get to people who use "text2" and vise versa.
Using Swift 2.0 with El Captain & Xcode 7.2.1
Elia, You need to add this to your app delegate. Which will arrive in a userInfo packet of data, which you can then parse to see which database/app sent it.
UIApplicationDelegate to the class
application.registerForRemoteNotifications() to the
func application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Than this method
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let notification = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! [String : NSObject])
let container = CKContainer(identifier: "iCloud.com")
let publicDB = container.publicCloudDatabase
if notification.notificationType == .Query {
let queryNotification = notification as! CKQueryNotification
if queryNotification.queryNotificationReason == .RecordUpdated {
print("queryNotification.recordID \(queryNotification.recordID)")
// Your notification
}
}
print("userInfo \(userInfo["ck"])")
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: self, userInfo:dataDict)
}
}
}
}
}
That'll get you started.
You can use this method to check your subscriptions programmatically, of course while your developing you can use the dashboard.
func fetchSubsInPlace() {
let container = CKContainer(identifier: "iCloud.com")
let publicDB = container.publicCloudDatabase
publicDB.fetchAllSubscriptionsWithCompletionHandler({subscriptions, error in
for subscriptionObject in subscriptions! {
let subscription: CKSubscription = subscriptionObject as CKSubscription
print("subscription \(subscription)")
}
})
}
And finally when you got it; you can this routine to ensure you capture any subscriptions you missed while your app was sleeping and make sure that subscriptions don't go to all your devices, once you treated them too.
func fetchNotificationChanges() {
let operation = CKFetchNotificationChangesOperation(previousServerChangeToken: nil)
var notificationIDsToMarkRead = [CKNotificationID]()
operation.notificationChangedBlock = { (notification: CKNotification) -> Void in
// Process each notification received
if notification.notificationType == .Query {
let queryNotification = notification as! CKQueryNotification
let reason = queryNotification.queryNotificationReason
let recordID = queryNotification.recordID
print("reason \(reason)")
print("recordID \(recordID)")
// Do your process here depending on the reason of the change
// Add the notification id to the array of processed notifications to mark them as read
notificationIDsToMarkRead.append(queryNotification.notificationID!)
}
}
operation.fetchNotificationChangesCompletionBlock = { (serverChangeToken: CKServerChangeToken?, operationError: NSError?) -> Void in
guard operationError == nil else {
// Handle the error here
return
}
// Mark the notifications as read to avoid processing them again
let markOperation = CKMarkNotificationsReadOperation(notificationIDsToMarkRead: notificationIDsToMarkRead)
markOperation.markNotificationsReadCompletionBlock = { (notificationIDsMarkedRead: [CKNotificationID]?, operationError: NSError?) -> Void in
guard operationError == nil else {
// Handle the error here
return
}
}
let operationQueue = NSOperationQueue()
operationQueue.addOperation(markOperation)
}
let operationQueue = NSOperationQueue()
operationQueue.addOperation(operation)
}
}

Resources