Closed kenchris closed 4 years ago
This is something JavaScript developers can like to do in the app code also, right? push using just data instead of a function is simpler. Maybe, we can add a non-normative Note in the spec with an example.
No that is the point, they cannot... yes it is easier to just write something static, but if you need to write something depending on what was already here (hence an update) you need to be able to look at the existing data first)
SNEP will overwrite records on the target anyway. I don't get what we want to achieve here. What is the use case? Read a tag and reuse those records for pushing (after modifying them)?
The underlying implementation will likely have to create a new SNEP message anyway, regardless how it's exposed in native or web APIs.
But if you want to "save" memory on bindings side that's possible, so I assume you are saying the API should be able to provide hints to the implementation that "in fact I want to do an update to a target"?
Yes you override... but sometimes what you want to write depends on what is already written. Like you want to create new records based on the data of old records.
Currently that is really really hard
Basically you want a hint from application to tell the implementation that please reuse the read buffers as write buffers after the app overrides them? :)
Currently that is really really hard
@kenchris Can you share how hard that would be?
I believe web developers would naively assume something like this shoud work.
const reader = new NDEFReader();
await reader.scan();
reader.onreading = async ({ message }) => {
// TODO: Update message.records[0].data
const writer = new NDEFWriter();
await writer.push(message);
};
I believe web developers would naively assume something like this shoud work.
That should indeed work and fulfills the use case in my view as well.
However, I didn't fully understand whether does Kenneth want to tell the implementation to make optimizations for updating if possible (instead of separate read/write cycle), or whether he just wanted a syntactic sugar for the whole read/write cycle. At least in Android, I don't think a full vertical read/write buffer optimization is possible, and at SNEP level certainly there is no optimization. So I think it's probably the syntactic sugar. Even then, it might add complexity/confusion to the API. I like the current simple way. Maybe we need more examples/experience with this use case.
@kenchris, how to move this forward? or close it?
There are different use-cases.
Sometimes I might want to push data and I will have special UI for that. (Creating a scanner with the side-effect of pushing seems a bit counter intuitive.)
In some cases, I might want to either cancel the push or modify what I push given what is already on the tag.
For instance, I could do a color combiner. Where I add a color. Say I add yellow, but as the card already has the value blue stored, I instead write green (combination of yellow and blue).
Those are very different use-cases than writing from a scan, which I actually don't really see a strong use-case for, though it could be used for auto initializing tags.
Do you mean updating a record in a pending push? Simplest is to cancel and push again. Otherwise there might be a race condition.
That would require two taps and it highly confusing for the user. Reading and writing is pretty fast, and for out testing with Alex we always got the read data before writing (which is why ignoreRead was introduced) and as creating the records is super fast, I don't see why this is not possible, unless it is due to the Android APIs. If you are too slow at creating the records and the user removed the phone, well then you will just get an error right.
You can even store the data if the tag has a serial number and then retry
That would require two taps and it highly confusing for the user.
If it's a pending push, no taps happened yet. But looks like you are after a different use case.
Reading and writing is pretty fast, and for out testing with Alex we always got the read data before writing
OK, with this I start to understand what you are after. You want to pass a transformation function to update a tag and you're confident all implementations can do the reading, processing and writing operations during the time of the tap?
yeah pretty much, that is now it works with most underlying tech support like NFC-A, NFC-B. They will read and write and send commands. So if that is supported I don't see why it wouldn't work for NDEF.
Anyway, if it fails, it will err, and require a second tap for the update, which is not worse from UX point of view.
However, it will clutter/confuse the API if push()
could take a function or a message from now, with different behavior (algorithm).
It will take a sequence of records or a method taking a sequence of records. It shouldn't change the algorithm a lot
This will all be solved by joining the reader and writer:
Currently, we override all records when pushing data - which is a bit foolish.
We do have the option to read the data being read just before the push, but as it is in a different callback, this is not easy to get right.
Instead of letting the push method just take data, we could additionally allow it to take a function and would receive the current records and return the data. A bit like when people modify arrays.
let filtered = [12, 5, 8, 130, 44].filter(value => value > 10);
But a bit like this pseudo code