1 2 Previous Next 28 Replies Latest reply: Apr 9, 2012 12:46 PM by David Bourne Go to original post
  • 15. Re: Check boxes in ibook author?
    David Bourne Level 2 Level 2 (345 points)

    MichiHenning wrote:

     

    a) Be careful with that approach. Dashcode has destroyed more than one project file for me, even though I saved the project successfully without error. Everything appears to be just fine. Then I close down Dashcode and try to open the project, and get an error message about a corrupted project file.

     

    b) Also watch things if you open a project and the canvas for the widget appears, but some of the elements of the widget are missing. Don't try and fix things when this happens. This is a bug in Dashcode, and if you keep working with the project, you will almost certainly end up with a corrupted project file. Instead, close the project immediately and the re-open it (using File -> Open). On the second attempt, the project file usually loads normally.

     

    c) I recommend to take frequent backups when using Dashcode. The danger of ending up with a corrupted project file is large and real. Save frequently and stash a copy of the saved file away somewhere else. That way, when Dashcode finally makes a mess of things, you won't lose too much work.

     

    d) Also, as you discovered, be wary if, during a save, you get a message about the project file not being found and getting prompted to pick a different save location. If that happens, it's over: you can no longer save the project anywhere, by any means, and the only way to recover is to kill Dashcode and use a backup copy.

     

    Michi.

     

    Thanks for the warnings. I think I've seen most of those problems ;-)

     

    a) This happened fairly regularly with the 'old' version. But strangely some of the those bad project files would come good after quitting Dashcode. I would always need to open the project file from within Dashcode. No success double-clicking on a project file.

     

    b) Canvas with missing elements. Yep. Close the project, quit Dashcode and restart. Sometime a couple of times.

     

    c) I have copies of projects now. In multiple places. For the first few projects I only had one or two copies. I only have two or three types of widgets so I've a number of versions of each type now.

     

    d) That's way I immediately try to save the project file when first opening it otherwise it was useless to continue. Close, quite, restart usually worked.

     

    It is a challenge but part of the 'fun' of programming. :-)

     

    Thanks for your insight. David

  • 16. Re: Check boxes in ibook author?
    David Bourne Level 2 Level 2 (345 points)

    I seem to have run into another problem. I've got localStorage keeping track of a state variable. Using one type of parameter versus another. I change some of the calculations and hide/unhide various labels based on the state stored in localStorage. I have a function call in the built-in load function to get the state and make the changes.

     

    However, it seems that load isn't called after the first opening of a particular widget. For example, I have load call a function to clear a graph. The first time it works and clears the graph. If I close the widget then open it again the graph doesn't get cleared.

    ...

    Ok, another observation. Closing the book and re-opening it calls load the first time each widget is opened. This behavour may be OK for my purposes but it would be better if I could make the load work each time the widget is opened or atleast read localStorage and make the changes..

     

    Any thoughts or suggesitons, Thanks, David

  • 17. Re: Check boxes in ibook author?
    MichiHenning Level 4 Level 4 (1,350 points)

    In Dashboard, you get a show() callback when the widget is shown in Dashboard, and a hide() callback when Dashboard is closed and the widget becomes invisible, but there is no corresponding callback in iBooks.

     

    The next best thing you can do is to record a time stamp in localStorage that marks the time the last state change was made. When retrieving values from local storage, check how much time has elapsed. If that is more than a minute (or whatever you deem appropriate), assume that the widget has been closed and reopened.

     

    Michi.

  • 18. Re: Check boxes in ibook author?
    K T Level 7 Level 7 (23,700 points)

    I'm not sure you can tweak your book to the point of working as you need in a kiosk environment. The only sure way is to reinstall the book between uses, since the normal scheme is based on one user on each device.

     

    I'd look into one of the chat widgets with remote interactivity instead, but I'm just guessing about your actual needs, etc.

     

    I can see where a book with testing widgets is an attractive proposal, but it amounts to a poor mans's app, I think :) Have considered using an app or perhaps an HTML5 website and just letting the users login there from whatever device...?

  • 19. Re: Check boxes in ibook author?
    MichiHenning Level 4 Level 4 (1,350 points)

    My book contains a calculator that has eight separate settings. There are no sensible default values for all settings. For example, one of the settings a choice between Celsius and Fahrenheit. That's a setting that should persist even beyond the book being closed and re-opened because it is unlikely to ever be changed.

     

    On the other hand, there are other settings for which there are default values that should reset when the widget is closed because these values are ephemeral. As is, there is no way to know inside a widget whether the widget is exposed the first time or not. The simple hide() and show() callbacks that are available in Dashboard would fix this.

    I'd look into one of the chat widgets with remote interactivity instead, but I'm just guessing about your actual needs, etc.

    Seeing that this requires connectivity, that may well be inappopriate. It also creates the problem of how to track persistent state and establish the client identity, and how to remove stale state in the server. And, seeing that local storage is involved, persistent state is obviously needed.

    I can see where a book with testing widgets is an attractive proposal, but it amounts to a poor mans's app, I think

    I don't think anyone mentioned testing widgets?

     

    Michi.

  • 20. Re: Check boxes in ibook author?
    MichiHenning Level 4 Level 4 (1,350 points)

    David Bourne wrote:

     

    Update: Removing the info button helps a lot. The sliders work better too. They still don't slide but a single tap usually get the job done. Thank you. db

    I'm sorry, I just saw this, otherwise I would have replied sooner.

     

    The sliders should work normally, that is, you should be able to put your finger on the thumb and drag the thumb left and right. If not, check what is actually contained in your HTML. If the slider is represented as a div with an AppleSlider class, that's the problem. Ditch the AppleSlider and replace the div with an ordinary HTML 5 input range element. That way, you get a (horizontal) slider that will work normally.

     

    Michi.

  • 21. Re: Check boxes in ibook author?
    David Bourne Level 2 Level 2 (345 points)

    MichiHenning wrote:

     

    In Dashboard, you get a show() callback when the widget is shown in Dashboard, and a hide() callback when Dashboard is closed and the widget becomes invisible, but there is no corresponding callback in iBooks.

     

    The next best thing you can do is to record a time stamp in localStorage that marks the time the last state change was made. When retrieving values from local storage, check how much time has elapsed. If that is more than a minute (or whatever you deem appropriate), assume that the widget has been closed and reopened.

     

    Michi.

    show() would be nice ;-)

     

    I tried adding a timer to the change state function but it didn't seem to do what was wanted. The timer didn't seem to keep running across opening of different widgets. I might try it again with some debug info and see if that really isn't working at wanted.

     

    My problem isn't puttting the state into localStorage, it is the reading of state from localStorage when re-opening the widget. Your idea is good but I don't think it would work since its the reading of localStorage that is missing when re-opening the widget. Thanks for your suggestion. David

  • 22. Re: Check boxes in ibook author?
    MichiHenning Level 4 Level 4 (1,350 points)

    David Bourne wrote:

     

    I tried adding a timer to the change state function but it didn't seem to do what was wanted. The timer didn't seem to keep running across opening of different widgets. I might try it again with some debug info and see if that really isn't working at wanted.

     

    My problem isn't puttting the state into localStorage, it is the reading of state from localStorage when re-opening the widget. Your idea is good but I don't think it would work since its the reading of localStorage that is missing when re-opening the widget. Thanks for your suggestion. David

    A time won't keep running when you close the book because that terminates the widget.

     

    What I mean was to get the current time. You can find it with something like this:

     

    var now = new Date();

    var hours = now.getHours();

    var minutes = now.getMinutes();

    var seconds = now.getSeconds();

     

    Write the current time into local storage, where it will persist. When you retrieve values from local storage, compare the retrieved time to the current one. If the difference is larger than, say, a minute (or whatever is appropriate for you), assume that the widget has been closed and reopened, and reset your widget state accordingly.

     

    Not perfect, but better than nothing at all.

     

    MIchi.

  • 23. Re: Check boxes in ibook author?
    David Bourne Level 2 Level 2 (345 points)

    MichiHenning wrote:

     

    A time won't keep running when you close the book because that terminates the widget.

     

    What I mean was to get the current time. You can find it with something like this:

     

    var now = new Date();

    var hours = now.getHours();

    var minutes = now.getMinutes();

    var seconds = now.getSeconds();

     

    Write the current time into local storage, where it will persist. When you retrieve values from local storage, compare the retrieved time to the current one. If the difference is larger than, say, a minute (or whatever is appropriate for you), assume that the widget has been closed and reopened, and reset your widget state accordingly.

     

    Not perfect, but better than nothing at all.

     

    MIchi.

    Michi,

     

    I haven't tried this, maybe tomorrow, but the problem is that when I re-open the widget the load() isn't called so it doesn't read localStorage. BTW, I wasn't closing the book, I was opening widget 1, closing widget 1, opening widget 2, closing widget 2, opening widget 1... the second opening of the widget 1 doesn't use load() so I don't get the localStorage information. Once I draw a line or change a value I can get localStorage as part of those actions. (Closing/opening the book works since load() is called when the book is opened ;-)

     

    I tried different variables in localStorage, one for each widget but that didn't seem to work either. For example I used getItem("getKC030602") and getItem("getKC030802") and the matching setItem("xxx",1) but the two localStorage items seem to have the same value. Length limit on name?

     

    Maybe I should try your syntax 'localStorage.myCounter = myCounter.toString();' I should be able to use something like--

    localStorage.getKC030602 = "1";

    localStorage.getKC030802 = "0";

    --to set two localStorage variable??

     

    Thanks for your suggestions. Documentation seems limited :-) and maybe I'm misunderstanding some of this... JavaScript stuff.

     

    David

  • 24. Re: Check boxes in ibook author?
    MichiHenning Level 4 Level 4 (1,350 points)

    David Bourne wrote:

     

    I haven't tried this, maybe tomorrow, but the problem is that when I re-open the widget the load() isn't called so it doesn't read localStorage. BTW, I wasn't closing the book, I was opening widget 1, closing widget 1, opening widget 2, closing widget 2, opening widget 1... the second opening of the widget 1 doesn't use load() so I don't get the localStorage information. Once I draw a line or change a value I can get localStorage as part of those actions. (Closing/opening the book works since load() is called when the book is opened ;-)

    David, here are some suggestions to try. (I have not coded this up, so I can't give you definitely advice.)

     

    If I understand you correcty, you want to know whether a widget has been closed and re-opened, as opposed to having been sitting there idle all along.

     

    I can think of three possible ways to deal with it.

     

    First option.

     

    Write the name of the currently running widget into local storage every time the state of that widget is updated. So, when widget 1 runs and slider is moved (or whatever), write "widget 1" into the key "lastWidget" in local storage. For widget 2, write "widget 2" into local storage, etc.

     

    In each widget, run a timer that fires once a second. Read the value of lastWidget in local storage from the timer. If the value is not the widget that is currently running, you know some other widget was run in the mean time. Therefore, your current widget was closed and reopened after some other widget ran, and you can take whatever user interface actions are necessary for that case.

     

    You need to use a timer because there is no other available callback hook.

     

    This will work, but only if a different widget has been run. If someone runs widget 1, closes it, and re-opens widget 1, you won't detect that widget 1 was closed.

     

    Second option.

     

    Run a timer that fires once a second. The timer retrieves a time from "lastTimeRun" and compares the value it reads to the current time. If the value it has read differs from the current time by, say, two seconds or more, you know that the widget stopped running some time in the past and was restarted.

     

    The assumption here is that timers will stop running when a widget isn't in the foreground. I think that's a reasonable assumption, but you should verify it. Set up your once-a-second timer and increment a variable from within the timer. Display the value of the variable in a test field in the widget. While the widget is running in the foreground, you should see the count tick over once per second. Now hit "x", wait thirty seconds, and tap on the widget to bring it into the foreground. If the value of the count goes up by 30 or so immediately, you know that the timer fires even when the widget is in the background. If the value goes up by 1 from the last value you saw before you closed the widget, you know that timers are still when the widget is in the background.

     

    Third option.

     

    You could try sessionStorage instead of localStorage. sessionStorage does not persist beyond the scope of the browser instance. The idea here is that you store the name of your widget into a variable and read it from a timer. If the widget reads the variable and finds that it isn't set, it clears the UI and then writes a value into the variable. For as long as the widget can read the value, you know that the session was alive for the entire time. Again, because there is no callback hook, you need to do this from a timer, say, once a second.

     

    The potential problem here is that it isn't clear where the session boundaries are in iBooks. (It's not documented.) The approach will work if (and only if) every time the user hits "x" to close a widget, that also wipes the session. Whether that is actually the case, I don't know, but you can easily find out by writing a small test case that writes trace to a text field in your widgets.

     

    One of these three approaches should do what you want. The session idea is probably most elegant, but relies on the session boundaries being in the right place, in particular, it relies on closing and re-opening the same widget wiping the session state.

     

    The second option will work, provided that timers stop running when the widget is in the background. (I would hope so, but I would test this first before committing to this approach.)

     

    Option 1 is guaranteed to work, but will not detect when the same widget is opened, closed, and opened again without some other widget having run in the mean time.

     

    And, of course, none of this hackery would be necessary if it were possible to get show and hide callback notifications in iBooks.

     

    Michi.

  • 25. Re: Check boxes in ibook author?
    MichiHenning Level 4 Level 4 (1,350 points)

    Maybe I should try your syntax 'localStorage.myCounter = myCounter.toString();' I should be able to use something like--

    localStorage.getKC030602 = "1";

    localStorage.getKC030802 = "0";

    --to set two localStorage variable??

    Whether you use dot notation or setItem() makes no difference. Dot notation is just syntactic sugar.

     

    Michi.

  • 26. Re: Check boxes in ibook author?
    David Bourne Level 2 Level 2 (345 points)

    Michi, thanks for your continued help. I was able to confirm with a Dashcode breakpoint that localStorage does allow more than one variable. I tried some with the timer function which seemed to work in Dashcode but not in my test iBook...

     

    I have the code snippet

    ---

        countTime();

    }

     

    function countTime()

    {

        var cc = document.getElementById("counter").value;

        cc++;

        var cv = document.getElementById("counter");

        cv.value = cc;

        var countID = setTimeout("countTime()",1000)

    }

    ---

    with a textfield 'counter'. The first line is in a function called by load(). The counter field is incremented in Dashcode but not in the widget in the iBook book? Strange.

     

    Hmm. Even stranger. I moved the setTimeOut line and it works now...

     

        countTime();

    }

     

    function countTime()

    {

        var countID = setTimeout("countTime()",1000)

        var cc = document.getElementById("counter").value;

        cc++;

        var cv = document.getElementById("counter");

        cv.value = cc;

    }

     

    Hopefully this will 'stick' and I can make some progress. The timer keeps incrementing when the widget is closed and opened. It resets when the book is closed and opened. This might be what I want. I can put a read localStorage in the countTime() function...

  • 27. Re: Check boxes in ibook author?
    MichiHenning Level 4 Level 4 (1,350 points)

    The code I had in mind was more something along the lines of this:

     

    var counter = 0;

    var timer;

     

    function load()

    {

        dashcode.setupParts();

        setTimeout(tick, 1000);

    }

     

    function tick()

    {

        if (typeof tick.textField == 'undefined')

        {

            tick.textField = document.getElementById("text");

        }

        timer = setTimeout(tick, 1000);

        ++counter;

        tick.textField.textContent = counter.toString();

    }

     

    In Dashboard, the timer keeps running when you close Dashboard. That's why the show() and hide() callbacks exist: you are supposed to cancel the timer in hide() and re-start it in show().

     

    When I run this in iBooks, unfortunately, the timer keeps running after closing the widget.

     

    So, this approach won't get you anywhere, I'm afraid. This also means that the session approach won't work because, clearly, if the script keeps running in the background, the session isn't being destroyed either.

     

    I'm afraid the only remaining option is to store the widget name in local storage. That will allow you detect whether another widget has been run in the meantime. It won't tell you though whether the same widget was run, closed, and opened again.

     

    Almost none of the code generated by Dashcode actually works in iBooks. It's sad that Apple recommend to use Dashcode without having made even a token effort to get things working in the iBook environment.

     

    Michi.

  • 28. Re: Check boxes in ibook author?
    David Bourne Level 2 Level 2 (345 points)

    Michi

     

    Thanks for your thoughtful suggestions. I may have to put this on the back burner for now. Hopefully the iBook version of JavaScript will mature to include some of the missing pieces. Probably should submit feedback suggestions at some point.

     

    Thanks, David

1 2 Previous Next