WCSession returns 'unreachable' when watchOS app is in background - watchkit

If Apple iWatch goes into the background, then WCSession gives us unreachable which also means that WCSession.default.isReachable is giving us FALSE.
I am not able to transfer data if the Apple watch is in the background.
let applicationData = ["value":"key"]
if let session = session, session.isReachable
{
WCSession.default.transferUserInfo(applicationData)
}

Related

How to create a liquidity pool on Raydium on Solana devnet?

Can anyone give me any advice on how to create an LP pool on the Solana devnet?
I planned this job for testing swaps between specific two tokens on the devnet using the Raydium protocol.
So, I need to create a swap pool on the devnet first.
To achieve this, I did it like below.
First of all, to list on the serum market, I cloned the Raydium-Dex repository on my mac and changed the Serum dex's program id from the mainnet to the devnet, and I success registered on the devnet serum. (Custom token with SOL pairs)
As a result, I got a serum market program id.
After that, I cloned the Raydium-frontend repository to create a liquidity pool. And modified wellknownToken.config.ts so that my custom tokens could be possible to create a new pool.
Finally, I could access the create pool UI from the localhost web UI.
I clicked Initialize Liquidity Pool button on the UI and got a Toast message Create a new pool Transaction Sent apparently.
However, It is not worked well. Because I can not find the transaction hash on the Solscan website.
I tracked the button's click event codes and I figured out one thing.
One of the result value of Liquidity.makeCreatePoolTransaction function has a null value, especially, feePayer.
const { transaction: sdkTransaction1, signers: sdkSigners1 } = Liquidity.makeCreatePoolTransaction({
poolKeys: sdkAssociatedPoolKeys,
userKeys: { payer: owner }
})
const testTx = await loadTransaction({ transaction: sdkTransaction1, signers: sdkSigners1 })
console.log('feepayer', testTx.feePayer?.toBase58()) // null
I felt this is not the preferred (good) way to create a swap pool on the Solana devnet, but I can not find a better way to achieve this task.
What am I missing? or What am I should read or learn?
please give me some advice on how to do it to make it works.
Thanks.
It looks like the transaction created with Liquidity.makeCreatePoolTransaction hasn't been sent to the network, so it doesn't exist anywhere. Be sure to send and confirm the transaction before trying to load it. You can use something like:
const { transaction: sdkTransaction1, signers: sdkSigners1 } = Liquidity.makeCreatePoolTransaction({
poolKeys: sdkAssociatedPoolKeys,
userKeys: { payer: owner }
});
await sendAndConfirmTransaction(connection, transaction, [wallet]);
Note that this requires a connection to send and a wallet to sign. More info at https://github.com/solana-labs/solana/blob/9ac2245970de90af30bff9d1f7f35cd2d8f2bf6d/web3.js/src/util/send-and-confirm-transaction.ts#L18
You might run into other issues though, because the Raydium program isn't deployed to devnet: https://explorer.solana.com/address/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8?cluster=devnet

WatchOS Background URLSession handle(_:) not called when app is not closed (lowered wrist)

I'm trying to create a Watch-App where I download data (around 30 MB).
Therefore I create a URLSession with a background configuration like so:
let config = URLSessionConfiguration.background(withIdentifier: "<some-id>")
self.session = URLSession(configuration: config, delegate: self, delegateQueue: .main)
and then start the download:
let request = URLRequest(url: "<some-url>", method: .GET)
self.task = session.downloadTask(with: request)
self.task.resume()
Since the user is not gonna stare at the watch for 5 minutes, I want to notify him with some haptic feedback when the download finished.
Therefore I wanted to use the handle(_:) function of the ExtensionDelegate. According to the documentation, this should be called with a WKURLSessionRefreshBackgroundTask when the download finished:
The system creates a background URLSession task when any of the following events occur:
Authentication is required to complete a background transfer.
All background transfers associated with a session identifier have completed (either successfully or unsuccessfully). https://developer.apple.com/documentation/watchkit/wkurlsessionrefreshbackgroundtask
This handle(_:) method is only called if I close my app though (pressing the crown), not when i lower my wrist to lock the screen.
I also noticed, that if I look at the watch again, the callbacks for urlSession(.. didWriteData ..) are not working anymore.
Am I missing something or is this even expected behaviour? I'm testing on a real Apple-Watch Series 4 with WatchOS 5 installed.

watchOS AudioRecorder has no input, doesn't ask for permission

I am using this code to show the AudioRecorder on the Apple Watch (taken from https://www.raywenderlich.com/345-audio-recording-in-watchos-tutorial)
let outputURL = chatMasterController.newOutputURL()
let preset = WKAudioRecorderPreset.narrowBandSpeech
let options: [String : Any] =
[WKAudioRecorderControllerOptionsMaximumDurationKey: 30]
presentAudioRecorderController(
withOutputURL: outputURL,
preset: preset,
options: options) {
[weak self] (didSave: Bool, error: Error?) in
guard didSave else { return }
print("finished audio to \(chatID) at \(outputURL)")
print(outputURL)
}
The Recorder pops up however it doesn't seem to take any input. The wave forms don't rise while speaking and trying to play the recording afterwards leaves me with 0.2seconds of silence no matter how long the recording is.
I've tried another app that's making use of the microphone and this app did ask me for permission to record audio. I have feared having dismissed the permission before so I have reinstalled my app which however didn't change anything - no permission being asked, no input being generated.
Is there something I've missed e.g. importing a lib?
I've now figured it out. You don't just need the Privacy - Microphone Usage Description string in your Watch app's plist - you also need to set it in the iPhone's plist.
Only setting it on the Watch does nothing, only setting it on the iPhone doesn't let you allow it on the Watch directly. So you need it on both.
No idea why this isn't documented anywhere but it fits Apple's "we are going downhill" movement :)

watchOS simple wakeup

Here is some watchOS code I have working on the Similator(Watch):
.....
let interval = 60.0
NSTimer.scheduledTimerWithTimeInterval(interval,
target: self,
selector: #selector(InterfaceController.timerDidEnd(_:)),
userInfo: nil, repeats: false)
.....
func timerDidEnd(timer:NSTimer) {
print("Time is over! Please wake up!")
}
From Xcode I run the app, the first part of the code above gets executed. Then I hit Command-Shift-H and the app goes in the background.
After one minute I see in the debugging console the message: Time is over! Please wake up!
All works as I expect. My question is:
What should I write inside the function timerDidEnd(), in order to have the app wake up from the background on the simulator, rather than just printing the current message in the debugger?
There's nothing you can write inside a timer action that will bring an app to the foreground. Only the user can resume an app.
If you think about it, it would confusing and disruptive for the user if an app could programmatically bring itself to the foreground whenever it wanted.
The only way to resume an app is by the user reacting to a notification. This is similar to what happens on the phone when the user taps notification actions from the home screen.

Send future clients to right monitor in awesome?

I'm trying to implement a very customized implementation of awesome.
I have two monitors. I'd like to have my first client always open on the left monitor (a Chrome window in kiosk mode), then all clients after open up on the right monitor.
Are there any custom layouts that accomodate this?
I'd be willing to program it myself, but I'm not sure how to bind a script to some kind of "new client" event.
The new client event is the manage event. It is emitted whenever, well, a new client gets managed by awesome.
To send the first client that ever appears to screen 1 and all following ones to screen 2, you could do something like this:
local first = true
client.connect_signal("manage", function(c)
if first then
c.screen = 1
else
c.screen = 2
end
first = false
end)

Resources