saveLocalData() when exiting application?

Is there a way to do this when a user closes the app. Not codea, but the app codea simulates.

No. I agree it would be useful to have an “app is being backgrounded” function though. Your best option may be to save whenever the relevant item of data changes.

@yojimbo2000

Alright, thank you very much! I’m going to release the first version of my app in a few days. So thank you and the entire codea team for all the help!

FWIW, I’ve found that saves to local data are so fast, that they rarely affect performance.

@Mark, really? I was saving a lot of data and when I had it saved to Keyboard(k) it caused slowdowns. But like I said I have a lot of Data saving at once.

@FearMe2142 I tried a saveLocalData with a string of 2 million characters, and there wasn’t any noticeable delay. I’m not sure what you mean by saved to Keyboard(k). Are you saving characters as they’re keyed in. If that’s the case, I don’t think someone can key fast enough that if you do save data, there will be a delay.

@dave1707

Yes as a user presses a key on the keyboard.


function Pages:Save() 
    Pages:SaveLine()
    Pages:SavePhoto()
    Pages:SaveWord()
end

function Pages:SaveLine()
    saveLocalData("Lines", #PageLine)
    for i,v in pairs(PageLine) do
        saveLocalData("Line"..i.."Words", #PageLine[i].words)
        saveLocalData("Line"..i.."Mode", PageLine[i].mode)
        saveLocalData("Line"..i.."rn", PageLine[i].rn)
        saveLocalData("Line"..i.."ln", PageLine[i].ln)
        for o,p in pairs(PageLine[i].words) do
            saveLocalData("Line"..i.."Word"..o, p.word)
            saveLocalData("Line"..i.."Word"..o.."bold", p.bold)
            saveLocalData("Line"..i.."Word"..o.."highlight", p.highlight)
            saveLocalData("Line"..i.."Word"..o.."italic", p.italic)
            saveLocalData("Line"..i.."Word"..o.."color", tostring(p.color))
        end
    end
end

function Pages:SavePhoto()
    saveLocalData("Photos", #Album)
    for i,v in pairs(Album) do
        j = "Documents:PhotoImage"..tostring(i)
        saveLocalData("PhotoX"..i, v.x)
        saveLocalData("PhotoY"..i, v.y)
        saveLocalData("PhotoW"..i, v.w)
        saveLocalData("PhotoH"..i, v.h)
        saveLocalData("PhotoMode"..i, v.mode)
        saveImage(j, v.img)
    end
end

function Pages:SaveWord()
    saveLocalData("Vocabulary", #Vocabulary)
    for i,v in pairs(Vocabulary) do
        saveLocalData("WordsLines"..i, v.lines)
        saveLocalData("WordsSelLines"..i, v.sellines)
        saveLocalData("WordsCurLines"..i, v.currentlines)
        saveLocalData("Stored"..i, #v.stored)
        for o,p in pairs(Vocabulary[i].stored) do
            saveLocalData("WordsStored"..i..o, p)
        end
    end
end

@FearMe2142 I didn’t realize you were saving so many different files in various loops. Can you give us an idea of what’s happening and when Pages:Save gets called in that scenario. Looking at the names of the files, it looks like a lot would be happening in between Pages:Save calls.

@FearMe2142 - I think you’ll find the problem is in the number of separate save calls you are making.

I suggest you combine them all into one text string, separating them with a special character. Then you just save once per frame, and you can read the string back and split it into individual items if you need to.

@FearMe2142 - And if you do create one text string, do it the fast way

Don’t do this. Concatenating text gets slower as the string gets longer, because Lua creates a fresh string each time.

s="|" --some separator character
txt=#PageLine[i].words
txt=txt .. "|" .. PageLine[i].mode
txt=txt .. "|" .. PageLine[i].rn
txt=txt .. "|"  .. PageLine[i].ln
--etc

Do this. Tables are fast.

tbl={}
s="|" --separator
tbl[#tbl+1]=#PageLine[i].words
tbl[#tbl+1]=PageLine[i].mode
tbl[#tbl+1]=PageLine[i].rn
tbl[#tbl+1]=PageLine[i].ln
-etc
txt=table.concat(tbl,s)

@dave1707

Well on the lines each one contains a table self.words = {}

I have each word separated so when its touched it can be bolder, italics, or highlighted.

I definitely shouldn’t have all 3 at once. However recently it has just been if k == RETURN that calls this.

Currently there isn’t a way from inside Codea to hook into the OS notifications about appDidEnterBackround and appWillQuit… etc, however you can write functions that will be called that serialise your apps state (as much as is feasible), you can then call this functionality from within your exported app by editing the app delegate files and extending the existing functionality.

Granted it would be nice for Codea to do this automatically hint hint and provide a function in the usual way. Personally I think this is most important on universal devices where the most common form of interruption is getting a phone call.

Given that writing a small serialised settings file is so quick in Codea what I’d recommend doing is outputting the state whenever the options / settings change, or whenever you move between screens. That way your app should always be able to recreate it’s state as much as possible.

Fixed

Put everything in 1 table and use json.encode and json.decode along with saveLocalData.

@dave1707

How do I unseparate it? I looked at patterns and didn’t understand.

I tried gmatch(“%b||”)

I would like all characters but |

Json libraries are thorough, but not very fast. I would avoid them if speed is important. Your own serialising with table.concat will be faster.

I’m having trouble with saveImage even when table.concat

I’m trying to save a photo the user takes with the camera and it still saves slow. The myKmage example won’t, however. V.img is the photo the user took.

function Pages:SavePhoto()
    saveLocalData(UserID..UniqueID..ChapterID.."Photos", #Album)
    for i,v in pairs(Album) do
        print(i.." iii")
        j = "Documents:PhotoImage"..tostring(i)..UserID..UniqueID..ChapterID
        tble = {}
        sep = "|"
--[[        tble[#tble+1] = v.x
        tble[#tble+1] = v.y
        tble[#tble+1] = v.w
        tble[#tble+1] = v.h
        tble[#tble+1] = v.ro
        tble[#tble+1] = v.mode]]
        txt = table.concat(tble, sep)
        if txt ~= readLocalData(UserID..UniqueID.."Photo"..i) then
            saveLocalData(UserID..UniqueID..ChapterID.."Photo"..i, txt)
            print("save"..i)
            saveImage(j, v.img)
        end
    end
end

You have print statements, which slow things down, and you have a loop, which may mean you are saving more than one photo at a time.