Project transfer iPad to iPad

@dave1707 - changed all out(0) to out(2) and found slicker generally plus transferred without problem.

@Bri_G I had no trouble changing to another name if a file already existed. I kept changing names to existing files and then to new files and each time everything worked OK. As for timing limits, I just tried different values until things worked. I don’t know that much about sockets, so it was all trial and error.

Here’s an updated version of my iPad to iPad project transfer. This needs to be run in landscape mode, currently supportedOrientations doesn’t work. To use, this program needs to be running on both iPads. There’s instructions, but basically this is controlled on the receiving iPad. If you want, you can get a list of all the projects on the sending iPad. You can enter what project you want to receive and it will be transferred to the receiving iPad. If needed, you can give the transferred project a different name to be created. Both iPad must be on the same system.

supportedOrientations(LANDSCAPE_ANY)    -- currently doesnt work

function setup() 
    rectMode(CENTER)
    message=""
    w=160
    h=50
    size=8000
    delay=.1
    cnt=0
    socket=require("socket")
    theirIp="0.0.0.0"  
    getMyIp()
    setMySocket()
    setTheirSocket()
    owSwitch=false
    owText="Don't overwrite"
    b1=button(100,HEIGHT-100,"Get their ip",getTheirIp)
    b2=button(100,HEIGHT-200,"Get their project list",getProjectList)
    b3=button(100,HEIGHT-300,"Get ProjectToGet",getProject)
    b4=button(100,HEIGHT-400,owText,overwrite)
    b4.col=color(0,255,0)
    parameter.text("ProjectToGet")
    parameter.text("nameToSave")
    fill(255)
    instructions1="Instructions... Should be run in landscape mode with print window showing.\
\
1.) Start this program on both devices, then on the receiving device do steps 2-7.\
2.) Press   Get their ip   to get the ip address of the other device.\
3.) Press   Get their project list   if you want to see the projects on the other device.\
4.) Enter the project name you want to receive in the  ProjectToGet   text area.\
5.) Enter a   nameToSave   if you want to save it as a different project name.\
6.) Tap the   Don't overwrite    button only if you want to overwrite the existing project.\
7.) Press   Get ProjectToGet   to receive the project from the other device.\
\
NOTE: Don't press RETURN when you enter anything in the text areas."
end

function draw()
    background(0)
    receiveTheirMessage()
    b1:draw()
    b2:draw()
    b3:draw()
    b4:draw()
    noFill()
    stroke(255, 243, 0, 255)
    strokeWidth(5)
    fill(115, 149, 173, 255)
    rect(WIDTH-300,HEIGHT-100,200,50)
    rect(WIDTH-300,HEIGHT-250,200,50)    
    fill(255)  
    text("My ip address",WIDTH-300,HEIGHT-50)
    text("Their ip address",WIDTH-300,HEIGHT-200)
    text(myIp,WIDTH-300,HEIGHT-100)
    text(theirIp,WIDTH-300,HEIGHT-250)
    text(message,WIDTH/2,HEIGHT/2)
    text(instructions1,WIDTH/2,200)
end

function touched(t)
    b1:touched(t)
    b2:touched(t)
    b3:touched(t)
    b4:touched(t)
end

function setMySocket()    
    server=socket.udp()
    server:setsockname(myIp,5544)
    server:settimeout(0)
end

function setTheirSocket()
    client=socket.udp()
    client:settimeout(0)
end

function getMyIp()
    server=socket.udp()
    server:setpeername("1.1.1.1",80)
    myIp,myPort=server:getsockname()
    ip1,ip2=string.match(myIp,"(%d+.%d+.%d+.)(%d+)")
end

function getTheirIp()
    client=socket.udp()
    client:settimeout(0)
    -- send a message to everyone on this network except to myself
    message="Their Ip wasn't received"
    for z=1,255 do
        if z~=tonumber(ip2) then
            client:setpeername(ip1..z,5544)
            client:send("get their ip")
        end
    end
end

function getProjectList()
    if theirIp=="0.0.0.0" then
        message="Their Ip wasn't received"
        return
    end
    client=socket.udp()
    client:settimeout(0)
    client:setpeername(theirIp,5544)
    client:send("getProjList")
end

function getProject()
    if theirIp=="0.0.0.0" then
        message="Their Ip wasn't received"
        return
    end
    if #ProjectToGet==0 then
        message="ProjectToGet is blank"
        return
    end
    client=socket.udp()
    client:settimeout(0)
    client:setpeername(theirIp,5544)
    client:send("getProject"..ProjectToGet)    
end

function receiveTheirMessage()
    local data,msg,port=server:receivefrom()
    if data~=nil then
        message=""
        theirIp=msg
        if data=="get their ip" then
            client=socket.udp()
            client:settimeout(0)
            client:setpeername(msg,5544)
            client:send("got their ip"..myIp)
                        
        elseif string.sub(data,1,12)=="got their ip" then
            theirIp=msg
            
        elseif data=="projectnotfound" then
            message="ProjectToGet not found"
            
        elseif data=="getProjList" then
            lst=listProjects("Documents") 
            pr=table.concat(lst,"\
")
            client=socket.udp()
            client:settimeout(0)
            client:setpeername(msg,5544)
            client:send("showProjList"..pr)
            
        elseif string.sub(data,1,12)=="showProjList" then
            output.clear()
            print(string.sub(data,13,#data)) 
                      
        elseif string.sub(data,1,10)=="getProject" then
            proj=string.sub(data,11,#data) 
            readProject(proj)

        elseif data=="start message" then
            output.clear()
            cnt=0
            newCode=""
            
        elseif data=="end message" then
            print("\
\
"..#newCode.." bytes received")
            createProj() 
            
        else
            cnt=cnt+1
            newCode=newCode..data
            print("received record "..cnt.."   "..#newCode.."  bytes")
        end
    end
end

function createProj()
    -- get project name and create the project
    for a in string.gmatch(newCode,"--PROJECT=(.-)=NAME") do
        projName=a
        if nameToSave~="" then
            projName=nameToSave
        end
        if projName~=nil then
            if hasProject(projName) then
                if owSwitch then
                    print("deleted project "..projName)
                    deleteProject(projName)
                else
                    print("project "..projName.." already exists.")
                    message="Project "..projName.." already exists.\
\
Check overwrite switch."
                    return
                end
            end
            print("Creating project  "..projName)
            message="Project   "..projName.."   Created"
            createProject(projName)
        else
            print(projName.."  not found in new code.")
        end
    end    
    -- get tab name and create the tabs and code
    for tabName,code in string.gmatch(newCode,"--TAB=(.-)=START\
(.-)(\
)--TAB==END") do
        print("created tab  "..tabName)
        saveProjectTab(projName..":"..tabName,code)
    end
    print("Done")
end    

function readProject(proj)
    origProject="--PROJECT="..proj.."=NAME\
"
    tabs=listProjectTabs(proj)
    if #tabs==0 then
        client = socket.udp()
        client:setpeername(theirIp,5544)
        client:settimeout(0)
        client:send("projectnotfound")
        return
    end
    for a,b in pairs(tabs) do
        origProject=origProject.."--TAB="..b.."=START\
"..readProjectTab(proj..":"..b).."\
--TAB==END\
"
    end
    sendMessage()
end

function sendMessage()
    if theirIp=="0.0.0.0" then
        message="Their Ip wasn't received"
        return
    end
    client = socket.udp()
    client:setpeername(theirIp,5544)
    client:settimeout(0)
    client:send("start message")
    sPos=1
    ePos=0
    cnt=0
    sendData=true
    while sendData do
        ePos=ePos+size
        if ePos>=#origProject then
            ePos=#origProject
            sendData=false
        end
        tempStr=string.sub(origProject,sPos,ePos)
        client:send(tempStr)
        cnt=cnt+1
        print("\
\
message "..cnt.." sent "..#tempStr.." bytes")
        sPos=sPos+size
        sTime=socket.gettime()+delay
        while socket.gettime()<sTime do  
            -- create a delay between multiple sends      
        end
    end
    print(#origProject.." total bytes sent")
    client:send("end message")
end

function overwrite()
    owSwitch=not owSwitch
    if owSwitch then
        b4.t="Allow Overwrite"
        b4.col=color(255,0,0)
    else
        b4.t="Don't Overwrite"
        b4.col=color(0,255,0)
    end
end

button=class()

function button:init(x,y,t,f)
    self.x=x
    self.y=y
    self.t=t    -- text
    self.f=f    -- function
    self.col=color(0,0,255)
end

function button:draw()
    stroke(255, 243, 0, 255)
    strokeWidth(5)
    fill(115, 149, 173, 255)
    rect(self.x,self.y,w,h)
    fill(self.col)
    text(self.t,self.x,self.y)
end

function button:touched(t)
    if t.state==BEGAN then
        if t.x>self.x-w/2 and t.x<self.x+w/2 and 
                t.y>self.y-h/2 and t.y<self.y+h/2 then
            self.f()
        end
    end
end

@dave1707 - tried this out with my iPad Pro and my iPad 2. Ran into a problem - couldn’t see the other pad. Checked, they were not on the same WiFi source. Corrected, both on same and ran fine.

Very useful, wanted to check projects ran on old pad. Ran into a problem straight away, couldn’t display an image on iPad 2. Probably memory - trying to display an 80 x 40 grid of 64x64 pixel sprites written to one image. Need to consider better ways of display - scrolling smaller image. A bit more complicated but less memory intensive.

Thanks again.

I have a program similar to daves that transcribes
each line of code into string then sends it to the ipad its connected to?

But I’ve come to realize two things: 1)you can easily transfer codea projects betwixt two ipad minis using air drop as long as you makesure both have air drop turned on, and you touch the id of the one you want to send it to and accept on the other end.

and 2? You only really have to use this type of program to transfer codea projects betwixt a currently up to date ipad and an ipad 2, since air drop doesn’t work with Ipad 2 s.

Ah, bri I see ypu do the same. I don’t know why apple has no love for the ipad 2s.

I get that they want people to buy new tablets but why not allow air drop support for thenold ones? I don’t know about daves but mine sometimes shuts off prematurely when sending.

@dave1707 could this be used to send data between 2 iPads while running the same app on both.

@Jazmal’s Now that we have OSC commands, this might be more of what you’re looking for. You didn’t say what you wanted to do with the data, but if it’s to create a game to be played on 2 different iPads, this code might be easier to understand. Put this on both iPads and enter the IP address of the other iPad in osc.host . Start both programs and slide your finger around the screen to move the sprite on the other iPad.

See this link also for project transfer using osc.

https://codea.io/talk/discussion/9464/the-new-osc-capability-in-2-7-is-wonderful#latest
function setup()
    host = osc.start()  -- address of this ipad
    print(host)
    osc.host = "192.168.254.15"  -- put address of other ipad here
    x,y=0,0      
end

function draw()
    background(0)
    sprite("Planet Cute:Character Horn Girl",x,y)
end

function osc.listen(address, ...)
    arg={...}
    x=arg[1]
    y=arg[2]
end

function touched(t)
    if t.state==MOVING then
        osc.send("/",t.x,t.y)
    end
end

@dave1707 thanks for the quick reply, the first iPad would generate some data then send it to the second iPad who will view it and make selections and then send the selections back to the first iPad.

@Jazmal’s The OSC code should be just fine for doing that. You can take the above code and modify it a little to do just what you want.

@Jazmal’s Here’s an example of sending and receiving a string of data. Put this code on both iPad and fill in the ip address of the other iPad. Tap the send parameter button.

function setup()
    parameter.action("send",send)
    host = osc.start()  -- address of this ipad
    print(host)
    osc.host = "192.168.254.27"  -- put address of other ipad here
end

function draw()
    background(0)
end

function osc.listen(address, ...)
    arg={...}
    -- receiving data
    if address=="/sent" then    -- this was sent data
        print("receiving "..arg[1])
    end
end

function send()
    str=""
    for z=1,100 do
        str=str.." "..z
    end
    print("sending "..str)
    -- sending data
    osc.send("/sent",str)   -- data sent
end

@dave1707 one thing I’ve found with osc is that it can only send a certain amount of data (equal to whatever the maximum size of a UDP datagram on the current connection). So sometimes strings get cutoff unfortunately.

@John A couple of weeks ago I did a test to see how much data I could send at one time with OSC. I kept making a string bigger and sending it to my other iPad. I finally reached a breaking point at 65,491 bytes. At 65,492 bytes I didn’t receive anything on the other iPad. When I was using sockets, the breaking point was somewhere in the 8,000 byte range. So OSC is a big improvement.