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

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.

Related

Is there a way to get a feedback from the Firebase extension "Resize Images" once it is completed? - Flutter Firebase Storage

I'm facing the following issue:
I upload an Image to Firebase Storage
//Start the upload
await StorageHandler.instance.uploadTask(mediaIDPath, largeFile);
Once the upload is completed, the Firebase Extension "Resize Image" will be triggered.
The Resized Imaged will be stored separately in another path in my FirebaseStorage
In order to make sure that the image is resized I'm waiting 4 seconds in my code (which is not the right way how to solve this problem)
//Start the upload
await StorageHandler.instance.uploadTask(mediaIDPath, largeFile);
//After the upload is completed, wait 4 seconds until the image is resized
await Future.delayed(Duration(seconds: 4));
Then I'm fetching the URL of the resized Image.
I need the download URL immediately in order to display image in a GridView as soon as the image is resized and added to the other path which I've mentioned in point 2.
//Start the upload
await StorageHandler.instance.uploadTask(mediaIDPath, largeFile);
//After the upload is completed, wait 4 seconds until the image is resized
await Future.delayed(Duration(seconds: 4));
//fetch the imageURL of the resized Image
gridURL = await StorageHandler.instance.getImageURLFromStorage(mediaIDPathResizedFile);
To wait 4 seconds is not the right way. Therefore I'm seeking for a possibility to get a feedback from the Storage that the Resize is completed that I can fetch the download URL afterwards.
I couldn't find any method in Firebase which provides this functionality.
Important note: I don't want to resize the image on client side to avoid more upload operations and keep the firebase costs at the minimum!
Does anyone have an idea for a workaround to avoid waiting 4 seconds in my case?
I hope I explained my problem clear enough and looking forward for helpful suggestions.
There is nothing built into the resize images extension to signal completion to the calling client.
The typical way to implement this yourself would be to create a Cloud Function that triggers when a file being written to Cloud Storage, and if the file is a thumbnail to implement the send a signal to the calling client (for example, by storing information in the metadata of the file on how to reach the client) through something like FCM, or one of Firebase's databases (Realtime Database, or Cloud Firestore).

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

How to make Kaa log upload event based instead of time based

I've only recently started to work with KaaIoT and I am wondering if there is another way to store a log bucked to the server.
/* some headers */
static void main_callback(void *context)
{
kaa_user_log_record_t *log_record = kaa_logging_time_collection_create();
log_record->test_time = kaa_string_copy_create("some_time");
kaa_logging_add_record(kaa_client_get_context(context)->log_collector, log_record, NULL);
}
/* some other configuration */
error = kaa_client_start(kaa_client, main_callback, kaa_client, 5);
When I execute this code, the string "some_time" will be stored to the server every 5 seconds.
I was wondering if there was an other way to do this, like upload the log to the server when I press my 'enter' key? But I can't seem to find a command for this.
To my understanding kaa_logging_add_record, just add the record to the storing bucket waiting to be sent according to the logging strategy you have defined. (https://kaaproject.github.io/kaa/autogen-docs/client-c/v0.10.0/kaa__logging_8h.html#af0fadc09a50f5e38603271a08c581417) . The parameter 5 sec in kaa_client_start is only a delay to cycle the call back function. If you want to register an event, first you have to store it in the log bucket and the timestamp if you want to record at what time happened. If you want to notify at the moment, the I think you should use Notifications or Events. I am also scratching my head in something similar and I wonder if there is a better way.

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.

Qt or PyQt - check when file is used by another process. Wait until finish copy

Good morning,
What is the best strategy for check when a big file o big directory has finished to copy?
I want wait until a file has finish fully to copy. Is there a code example in q
I'm working on mac os x.
thanks
Update
I use QFileSystemWatcher. the problem is that I receive file or directory change notification when o copy it is in progress. So user copy a big folder (inside many files), the operating system copy process start, it take 5 minuts, but in same times my application receive file changed notification. This is a problem because when i receive a change notification my application start for doing some operations on that files, but the copy is already in progress!!!!
There is only one reliable way to do this: Change the copy process to write to temporary files and then rename them after the copy is finished.
That way, you can ignore new files which end with .tmp and rename is an atomic operation.
If you can't change the copy process, all you can do is add a timer to wait for, say, half an hour to make sure the copy is really finished.
A more fine grained (and more risky) approach is to add a loop that check the file size and stops when the file size doesn't change for a certain time but that's also hard to get right.
Worse, this doesn't prevent you from reading partial files (when the copy process was terminated in the middle).
I think that the QFileSystemWatcher is the right start for you to get to the point of monitoring for changes, but as you have found, these changes are ANY changes. From this point, I think it should be easy enough for you to just check the modification time of the file.
Here is a simple example of a Watcher class that will let you specify a file to monitor and see if it has been modified after a given time. It can run a callback or emit a signal that anyone can watch:
import os.path
import time
from PyQt4 import QtCore
class Watcher(QtCore.QObject):
fileNotModified = QtCore.pyqtSignal(str)
MOD_TIME_DIFF = 5 #seconds
def __init__(self, aFile, callback=None, checkEvery=5):
super(Watcher, self).__init__()
self.file = aFile
self.callback = callback
self._timer = QtCore.QTimer(self)
self._timer.setInterval(checkEvery*1000)
self._timer.timeout.connect(self._checkFile)
def _checkFile(self):
diff = time.time() - os.path.getmtime(self.file)
if diff > self.MOD_TIME_DIFF:
self._timer.stop()
self.fileNotModified.emit(self.file)
if self.callback:
self.callback()
def start(self):
self._timer.start()
def stop(self):
self._timer.stop()
An example of using it:
def callbackNotify():
print "Callback!"
def signalNotify(f):
print "Signal: %s was modified!" % f
# You could directly give it a callback
watcher = Watcher("/path/to/file.file", callback=callbackNotify)
# Or could use a signal
watcher.fileNotModified.connect(signalNotify)
# tell the watcher timer to start checking
watcher.start()
## after the file hasnt been modified in 5 seconds ##
# Signal: /path/to/file.file was modified!
# Callback!
Try using QtConcurrent framework.
In particular, check out QFuture and QFutureWatcher. You can execute asynchronous copy operations inside a QFuture object and monitor its progress through signals and slots with a watcher.
bool copyFunction() {
// copy operations here, return true on success
}
MyHandlerClass myObject;
QFutureWatcher<bool> watcher;
connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished()));
QFuture<bool> future = QtConcurrent::run(copyFunction);
Since you have no control on the external application, my suggestion is that you lock the files while you work on them. In this way other programs will not be able to access them while locked.
Alternatively, if you have access to the other program's source, you should implement some form of inter process communication,via sockets, messages or whatever method you prefer.

Resources