Me and my friend are working on an fan app for a friends band and it's supposed to pull their facebook page feed/statuses into a tableView but it only returns one empty cell. Since the app is a secret i linked to the graph for ansca, the bands graph looks just like this one.
https://developers.facebook.com/tools/explorer?method=GET&path=79415735871%2Ffeed
I don't know why it only returns one cell, if I use "me/friends" and follow the corona docs then it returns all my friends.
edit: Updated and edited the code.
Thanks/David
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | local storyboard = require( "storyboard" ) local scene = storyboard.newScene() local widget = require("widget") local json = require("json") local facebook = require("facebook") ----------------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION -- -- NOTE: Code outside of listener functions (below) will only be executed once, -- unless storyboard.removeScene() is called. -- -------------------------------------------------------------------------------------- local facebookAppId = "xxxxxxxxxxxxxxxx" local facebookUserId = "xxxxxxxxxxxxxx" local anscaID = "79415735871" local response local data local myTableView; -- Called when the scene's view does not exist: function scene:createScene( event ) local group = self.view local tableViewOptions = { top = 64, left = 0, width = 320, height = 368, friction = 0.935, -- maskFile = "assets/masks/mask-370.png" } myTableView = widget.newTableView(tableViewOptions) group:insert(myTableView) local fbLogin = function(event) if event.type == "session" and event.phase == "login" then facebook.request(anscaID.."/statuses") elseif event.type == "request" then response = json.decode(event.response) data = response.data for i = 1, #data do local function onRowRender( event ) local row = event.target local rowGroup = event.view local userName local pubDateText local messageText local likesCount row.userName = display.newRetinaText(rowGroup, data[i].from.name, 0, 0, "Helvetica-Bold", 14) row.userName:setReferencePoint(display.TopLeftReferencePoint) row.userName.x = 10 row.userName.y = 5 row.userName:setTextColor(33, 33, 33, 255) row.messageText = display.newRetinaText(rowGroup, data[i].message, 0, 0, 300, 88, "Helvetica", 12) row.messageText:setReferencePoint(display.TopLeftReferencePoint) row.messageText.x = 10 row.messageText.y = row.userName.height +15 row.messageText:setTextColor(66, 66, 66, 255) row.pubDateText = display.newRetinaText(rowGroup, data[1].updated_time, 0, 0, "Helvetica", 12) row.pubDateText(display.TopLeftReferencePoint) row.pubDateText.x = 10 row.pubDateText.y = row.messageText.height +15 row.pubDateText(66, 66, 66, 255) row.likesCount = display.newRetinaText(rowGroup, data[1].likes.count, 0, 0, "Helvetica", 12) row.likesCount(display.TopLeftReferencePoint) row.likesCount.x = row.pubDateText.width + 30 row.likesCount.y = row.messageText.height +15 row.likesCount(66, 66, 66, 255) end --onRowRender closed local rowHeight = 128; local lineColor = {0, 0, 0, 255} local rowColor = {255, 255, 255, 255} myTableView:insertRow{ height = rowHeight, lineColor = lineColor, rowColor = rowColor, onRender = onRowRender } end--for ends end end facebook.login( facebookAppId, fbLogin, {"read_stream"}) -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view -- Do nothing end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view -- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.) end -- If scene's view is removed, scene:destroyScene() will be called just prior to: function scene:destroyScene( event ) local group = self.view -- INSERT code here (e.g. remove listeners, remove widgets, save state variables, etc.) end ----------------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION ----------------------------------------------------------------------------------------- -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", scene ) -- "enterScene" event is dispatched whenever scene transition has finished scene:addEventListener( "enterScene", scene ) -- "exitScene" event is dispatched whenever before next scene's transition begins scene:addEventListener( "exitScene", scene ) -- "destroyScene" event is dispatched before view is unloaded, which can be -- automatically unloaded in low memory situations, or explicitly via a call to -- storyboard.purgeScene() or storyboard.removeScene(). scene:addEventListener( "destroyScene", scene ) ----------------------------------------------------------------------------------------- return scene |
Thanks Danny,
I realized that too after a while but there are some problems still.
When I start the app it fetch the data from facebook I requested but not all of it, some posts have no date and some no message and the user name never returns. Some cells are empty (happens with "me/friends" too). This only works with "me/statuses" and not "me/feed"
I have extended permissions etc to fetch everything I need but this is driving me crazy because from what I understand I can change me to any user I want and get their statuses if their profile is public.
Another problem is that it only returns the data every other time and I have to remove the app permission from my facebook for it to reload the statuses and it's not every time it fetch the data either.
Last but not least, I use this in a tabBar app and when I switch tabs back and forth the tableview gets removed. What would cause that, because I don't remove it?
David,
try save the response data to a local file and then read from there to populate the tableView. If you do that then you can check sandbox if you get all data you request/have permissions to read.
Danny
Well, I did print the event.response and it shows the ansca status updates, however as adviced I tried to write the content to a file but it does not write nor does it populate the tableView anymore, what am I missing here?
Since json.decode returns a lua table called response and I write the lua table to the text file, should I instead write the event.response to a json file and decode that file instead?
Thanks guys.
David
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | local storyboard = require( "storyboard" ) local scene = storyboard.newScene() local widget = require("widget") local json = require("json") local facebook = require("facebook") ----------------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION -- -- NOTE: Code outside of listener functions (below) will only be executed once, -- unless storyboard.removeScene() is called. -- -------------------------------------------------------------------------------------- local facebookAppId = "xxxxxxxxxxxxxxxx" local facebookUserId = "xxxxxxxxxxxxxx" local anscaID = "79415735871" local response local data local myTableView; -- Called when the scene's view does not exist: function scene:createScene( event ) local group = self.view local tableViewOptions = { top = 64, left = 0, width = 320, height = 368, friction = 0.935, -- maskFile = "assets/masks/mask-370.png" } myTableView = widget.newTableView(tableViewOptions) group:insert(myTableView) local fbLogin = function(event) if event.type == "session" and event.phase == "login" then facebook.request(anscaID.."/statuses") elseif event.type == "request" then response = json.decode(event.response) data = response.data local path = system.pathForFile( "fbData.txt", system.DocumentsDirectory ) -- io.open opens a file at path. returns nil if no file found local file = io.open( path, "r" ) if file then -- read all contents of file into a string local contents = file:read( "*a" ) io.close( file ) else -- create file b/c it doesn't exist yet file = io.open( path, "w") file:write(response) io.close( file ) end for i = 1, #data do local function onRowRender( event ) local row = event.target local rowGroup = event.view local userName local pubDateText local messageText local likesCount row.userName = display.newRetinaText(rowGroup, data[i].from.name, 0, 0, "Helvetica-Bold", 14) row.userName:setReferencePoint(display.TopLeftReferencePoint) row.userName.x = 10 row.userName.y = 5 row.userName:setTextColor(33, 33, 33, 255) row.messageText = display.newRetinaText(rowGroup, data[i].message, 0, 0, 300, 88, "Helvetica", 12) row.messageText:setReferencePoint(display.TopLeftReferencePoint) row.messageText.x = 10 row.messageText.y = row.userName.height +15 row.messageText:setTextColor(66, 66, 66, 255) row.pubDateText = display.newRetinaText(rowGroup, data[1].updated_time, 0, 0, "Helvetica", 12) row.pubDateText(display.TopLeftReferencePoint) row.pubDateText.x = 10 row.pubDateText.y = row.messageText.height +15 row.pubDateText(66, 66, 66, 255) end --onRowRender closed local rowHeight = 128; local lineColor = {0, 0, 0, 255} local rowColor = {255, 255, 255, 255} myTableView:insertRow{ height = rowHeight, lineColor = lineColor, rowColor = rowColor, onRender = onRowRender } end--for ends end end facebook.login( facebookAppId, fbLogin, {"read_stream"}) -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view -- Do nothing end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view -- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.) end -- If scene's view is removed, scene:destroyScene() will be called just prior to: function scene:destroyScene( event ) local group = self.view -- INSERT code here (e.g. remove listeners, remove widgets, save state variables, etc.) end ----------------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION ----------------------------------------------------------------------------------------- -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", scene ) -- "enterScene" event is dispatched whenever scene transition has finished scene:addEventListener( "enterScene", scene ) -- "exitScene" event is dispatched whenever before next scene's transition begins scene:addEventListener( "exitScene", scene ) -- "destroyScene" event is dispatched before view is unloaded, which can be -- automatically unloaded in low memory situations, or explicitly via a call to -- storyboard.purgeScene() or storyboard.removeScene(). scene:addEventListener( "destroyScene", scene ) ----------------------------------------------------------------------------------------- return scene |
Hi David.
You can use this function to save a table (using json)
1 2 3 4 5 6 7 | local function saveTable(fp, theTable) local path = system.pathForFile(fp, system.DocumentsDirectory) file = io.open(path, "w") file:write(json.encode(theTable)) io.close(file) end |
Danny,
But why put it in a function like that?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | local fbLogin = function(event) if event.type == "session" and event.phase == "login" then facebook.request(anscaID.."/statuses") elseif event.type == "request" then response = json.decode(event.response) local path = system.pathForFile("fbData.json", system.DocumentsDirectory) file = io.open(path, "w") file:write(json.encode(response)) io.close(file) end end |
Sorry but I'm a little lost, all this stuff really confuses me right now. I've already tried this and it doesn't write the file to DocumentsDirectory when I check the files on my device. At first I though it was bcause .json format but then I tested .txt and it didn't change a thing.
Thanks
D.
Danny,
Just tried this too and no file was created.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | local response = {} local fbLogin = function(event) if event.type == "session" and event.phase == "login" then facebook.request(anscaID.."/statuses") elseif event.type == "request" then response = json.decode(event.response) end end local function saveTable() local path = system.pathForFile("fbData.json", system.DocumentsDirectory) file = io.open(path, "w") file:write(json.encode(response)) io.close(file) end |
Thanks again Danny.
This is an odd one, I will check out your code on my computer first thing in the morning for you and try and get this resolved
Danny,
I copied the print from the response and saved it to a json file so now just to test populating the tableView I try to get the data from that file I intend to save from the respons from facebook.
The problem I face now is that it won't populate the tableView cell, I think I'm all messed up because the lua table I get from the json file is so nested
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | ----------------------------------------------------------------------------------------- -- -- view1.lua -- ----------------------------------------------------------------------------------------- local storyboard = require( "storyboard" ) local scene = storyboard.newScene() local json = require("json") local widget = require("widget") ----------------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION -- -- NOTE: Code outside of listener functions (below) will only be executed once, -- unless storyboard.removeScene() is called. -- ----------------------------------------------------------------------------------------- -- Called when the scene's view does not exist: function scene:createScene( event ) local group = self.view -- create a white background to fill screen local bg = display.newRect( 0, 0, display.contentWidth, display.contentHeight ) bg:setFillColor( 255 ) -- white local toolBar = display.newRect(320, 44, 0, 20) toolBar:setFillColor(100, 100, 100, 255) group:insert(toolBar) local tableViewOptions = { top = 64, left = 0, width = 320, height = 368, friction = 0.935, maskFile = "assets/mask-370.png" } local myTableView = widget.newTableView(tableViewOptions) group:insert(myTableView) local jsonFile = function( filename, base ) -- set default base dir if none specified if not base then base = system.DocumentsDirectory; end -- create a file path for corona i/o local path = system.pathForFile( filename, base ) -- will hold contents of file local contents -- io.open opens a file at path. returns nil if no file found local file = io.open( path, "r" ) if file then -- read all contents of file into a string contents = file:read( "*a" ) io.close( file ) -- close the file after using it end return contents end local fbData = json.decode( jsonFile( "anscaFBStatus.json" ) ) for i = 1, #fbData do local function onRowRender( event ) local row = event.target local rowGroup = event.view local userName; local pubDateText; local messageText; local likesCount; row.userName = display.newRetinaText(rowGroup, fbData[i].data.name, 0, 0, "Helvetica-Bold", 14) row.userName:setReferencePoint(display.TopLeftReferencePoint) row.userName.x = 25; row.userName.y = 8; row.userName:setTextColor(123, 89, 123, 255) row.messageText = display.newRetinaText(rowGroup, fbData[i].data.message, 0, 0, 248, 0, 12) row.messageText:setReferencePoint(display.TopLeftReferencePoint) row.messageText.x = 25; row.messageText.y = row.userName.height + 8; row.messageText:setTextColor(123, 0, 46, 255) row.pubDateText = display.newRetinaText(rowGroup, fbData[i].data.updated_time, 0, 0, "Helvetica", 10) row.pubDateText:setReferencePoint(display.TopLeftReferencePoint) row.pubDateText.x = 25; row.pubDateText.y = row.messageText.height + 30; row.pubDateText:setTextColor(123, 123, 123, 255) row.likesCount = display.newRetinaText(rowGroup, fbData[i].data.likes.count, 0, 0, "Helvetica", 10) row.likesCount:setReferencePoint(display.TopLeftReferencePoint) row.likesCount.x = row.pubDateText.width + 45; row.likesCount.y = row.messageText.height + 30; row.likesCount:setTextColor(123, 123, 123, 255) end --onRowRender closed local rowHeight = 120; local lineColor = {0, 0, 233, 255} local rowColor = {255, 250, 250, 255} myTableView:insertRow{ height = rowHeight, lineColor = lineColor, rowColor = rowColor, onRender = onRowRender } end--for ends end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view -- Do nothing end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view -- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.) end -- If scene's view is removed, scene:destroyScene() will be called just prior to: function scene:destroyScene( event ) local group = self.view -- INSERT code here (e.g. remove listeners, remove widgets, save state variables, etc.) end ----------------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION ----------------------------------------------------------------------------------------- -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", scene ) -- "enterScene" event is dispatched whenever scene transition has finished scene:addEventListener( "enterScene", scene ) -- "exitScene" event is dispatched whenever before next scene's transition begins scene:addEventListener( "exitScene", scene ) -- "destroyScene" event is dispatched before view is unloaded, which can be -- automatically unloaded in low memory situations, or explicitly via a call to -- storyboard.purgeScene() or storyboard.removeScene(). scene:addEventListener( "destroyScene", scene ) ----------------------------------------------------------------------------------------- return scene |
I was gonna add the json file but it was 2500 lines.... so I post the link to graphexplorer instead so you can copy the json instead.
https://developers.facebook.com/tools/explorer/?method=GET&path=79415735871%2Fstatuses
Also, is there a way to get a floating cell height depending on how much text there is in each status post?
Something like:
rowGroup.height or rowGroup.contentHeight
Here's the first post from ansca facebook feed, if I would use the json response to populate the tableView it would be very slow so if I write this file to local document and open it and populate my tableView from there it would be faster and I could even populate with the old file if there were an error.
When I populated the tableView right from the response data from facebook I ended up with empty cells, no name etc...., sometimes I didn't even get the data to populate the tableCells
If anyone glance at the code above I did it like this:
data[i].from.name
data[i].message
data[i].updated_time
data[i].likes.count
So if I follow the advice I got from this thread and decode the json file to a lua table how would I write the above then? Because it doesn't work like that.
First post from ansca facebook statuses.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | { "data": [ { "id": "79415735871_10150523274245872", "from": { "name": "ANSCA Inc", "category": "Internet/software", "id": "79415735871" }, "message": "What would a Corona SDK Super Bowl commercial look like? \nHmmm....", "actions": [ { "name": "Comment", "link": "https://www.facebook.com/79415735871/posts/10150523274245872" }, { "name": "Like", "link": "https://www.facebook.com/79415735871/posts/10150523274245872" } ], "type": "status", "application": { "name": "Facebook for iPhone", "canvas_name": "fbtouch", "namespace": "fbtouch", "id": "6628568379" }, "created_time": "2012-02-06T00:54:26+0000", "updated_time": "2012-02-06T04:04:46+0000", "likes": { "data": [ { "name": "Peach Pellen", "id": "100001834601731" } ], "count": 5 }, "comments": { "data": [ { "id": "79415735871_10150523274245872_20797466", "from": { "name": "Chris Renshaw", "id": "100000017425133" }, "message": "two programming teams huddle for design, lineup on laptops, and create a game first for the win!", "created_time": "2012-02-06T01:18:26+0000" }, { "id": "79415735871_10150523274245872_20799977", "from": { "name": "Robert Bingham", "id": "100000630603216" }, "message": "Corona Logo flies in. Some Particle Candy effects i.e. Flash logo blows up, scrolling list of #1 apps made with Corona... Fade to black.... enter tag line: In the time it took you to watch the Super Bowl you too could have created a #1 app, using Corona SDK... fade out to the Corona Logo. End. All the while dramatic music playing", "created_time": "2012-02-06T04:04:46+0000", "likes": 2 } ], "count": 5 } } ] } |
This should populate from the lua table, now use the data table I set up for your tableView Cell items.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | for i = 1, #fbData.data do local function onRowRender( event ) local row = event.target; local rowGroup = event.view; local userName; local pubDateText; local messageText; local likesCount; data[i] = {} data[i].name = fbData.data[i].from.name data[i].message = fbData.data[i].message data[i].pubDate = fbData.data[i].updated_time data[i].likes = fbData.data[i].likes.count |
@Danny, @lano78
Thanks for that, now I need to fix the problem why the facebook response doesn't write to file so I can use the "local" json file.
If I put a forward declaration for cellHeight and then get the rowGroup.height (I can get that value I noticed) then could I pass that in as the height of the row?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | -- forward declaration. local cellHeight for i = 1, #fbData.data do -- All tableView cell stuff cellHeight = rowGroup.height + 4 -- added 4pixel padding end local rowHeight = cellHeight -- this doesn't set the height local lineColor = {233, 233, 233, 255} local rowColor = {250, 250, 250, 255} myTableView:insertRow{ height = rowHeight, lineColor = lineColor, rowColor = rowColor, onRender = onRowRender } |
The problem with your facebook response is when you tell corona to write to a file with Danny's function, corona doesn't create the file because you didn't tell it to do so.
If you change the saveTable function to this and add it above your facebook login function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function saveTable( fileName, responseTable ) local jsonString = json.encode( responseTable ) local path = system.pathForFile( fileName, system.DocumentsDirectory ) local file = io.open( path, "w" ) if file then file:write( jsonString ) io.close( file ) end end |
then add this to the login function below the response, then it should work for you.
1 | saveTable("theResponse.json", response) |
Then below all this you just decode the json file and add it to the tableView.
Hope it helps.
@lano78
Thanks sooo much!
@Danny/@lano78
Still there's one odd problem, when we build for device the app crashes when pressing the facebook tabButton but if we comment out the openJson file and tableView stuff and build again the app works fine but no status message show. The date and title does but the message don't. Why is that?
it's like the writing to the file and opening the local file collides, like I try to read the file before it's written. Could it be that, how would I solve this because I have no clue?
Also is there a more efficient way to write this type of code, how would you do it?
And yes lano78, the json file gets written now.
Another thing I tried was to set the first cell to have greater height to fit an image but that didn't work, also I want to have a few cells with ads. Have any clues how to do this?
thanks for all the help.
David
Thanks for the great help,
Here's the code I have now, If we build this for device the app crash/screen go black when this tab is pressed. However, if we comment out and only login to facebook and save the json response it will work. Then if we un-comment the and build for device, load it to device it will run fine but the status messages will not show, the userName and pubDate does show.
Can someone please help me with this, I can't understand why it happens.
Thanks/David
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | local storyboard = require( "storyboard" ) local scene = storyboard.newScene() local widget = require("widget") local json = require("json") local facebook = require("facebook") ----------------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION -- -- NOTE: Code outside of listener functions (below) will only be executed once, -- unless storyboard.removeScene() is called. -- -------------------------------------------------------------------------------------- local fbAppID = "432761358800056" -- Fake ID, replace with yours local anscaUserID = "79415735871" local response local data local myTableView; -- Called when the scene's view does not exist: function scene:createScene( event ) local group = self.view local tableViewOptions = { top = 64, left = 0, width = 320, height = 368, friction = 0.935, -- maskFile = "assets/masks/mask-370.png" } myTableView = widget.newTableView(tableViewOptions) group:insert(myTableView) function saveTable( filename, dataTable ) local jsonString = json.encode( dataTable ) local path = system.pathForFile( filename, system.DocumentsDirectory ) local file = io.open( path, "w" ) if file then file:write( jsonString ) io.close( file ) end end local jsonFile = function( filename, base ) if not base then base = system.DocumentsDirectory; end local path = system.pathForFile( filename, base ) local contents local file = io.open( path, "r" ) if file then contents = file:read( "*a" ) io.close( file ) end return contents end local onLoginSuccess = function() facebook.request(anscaUserID.."/statuses") end local function fbListener( event ) if event.isError then native.showAlert( "ERROR", event.response, { "OK" } ) else if event.type == "session" and event.phase == "login" then onLoginSuccess() elseif event.type == "request" then local response = json.decode(event.response); saveTable("fbData.json", response) end end end -- Un comment here and build for device, upload to device again and it works. --[[ fbData = json.decode( jsonFile( "fbData.json", system.DocumentsDirectory ) ) data = {} for i = 1, #fbData.data do local function onRowRender( event ) local row = event.target local rowGroup = event.view local userName; local pubDateText; local messageText; data[i] = {} data[i].name = fbData.data[i].from.name data[i].message = fbData.data[i].message data[i].pubDate = fbData.data[i].updated_time row.userName = display.newRetinaText(rowGroup, data[i].name, 0, 0, "Helvetica-Bold", 14) row.userName:setReferencePoint(display.TopLeftReferencePoint) row.userName.x = 15; row.userName.y = 6; row.userName:setTextColor(66, 66, 66, 255) row.messageText = display.newRetinaText(rowGroup, data[i].message , 0, 0, 248, 0, 12) row.messageText:setReferencePoint(display.TopLeftReferencePoint) row.messageText.x = 15; row.messageText.y = row.userName.height + 8; row.messageText:setTextColor(66, 66, 66, 255) row.pubDateText = display.newRetinaText(rowGroup, data[i].pubDate, 0, 0, "Helvetica", 10) row.pubDateText:setReferencePoint(display.TopLeftReferencePoint) row.pubDateText.x = 15; row.pubDateText.y = row.messageText.height + 30; row.pubDateText:setTextColor(66, 66, 66, 255) end --onRowRender closed local rowHeight = 130; local lineColor = {0, 0, 0, 255} local rowColor = {250, 250, 250, 255} myTableView:insertRow{ height = rowHeight, lineColor = lineColor, rowColor = rowColor, onRender = onRowRender } end--for ends --]] facebook.login( fbAppID, fbLogin, {"read_stream"}) end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view -- Do nothing end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view -- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.) end -- If scene's view is removed, scene:destroyScene() will be called just prior to: function scene:destroyScene( event ) local group = self.view display.remove(myTableView) myTableView = nil group:removeSelf() group = nil -- INSERT code here (e.g. remove listeners, remove widgets, save state variables, etc.) end ----------------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION ----------------------------------------------------------------------------------------- -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", scene ) -- "enterScene" event is dispatched whenever scene transition has finished scene:addEventListener( "enterScene", scene ) -- "exitScene" event is dispatched whenever before next scene's transition begins scene:addEventListener( "exitScene", scene ) -- "destroyScene" event is dispatched before view is unloaded, which can be -- automatically unloaded in low memory situations, or explicitly via a call to -- storyboard.purgeScene() or storyboard.removeScene(). scene:addEventListener( "destroyScene", scene ) ----------------------------------------------------------------------------------------- return scene |
Anyone had a chance to look at this problem?
Thanks in advance.
David
When I run the entire code in the simulator it's fine and no errors but when it's on device it crash. How can I get the error messages I usually get in the simulator to help me when testing on device?
I've tries to narrow down the problem by comment out parts of the code and since the login part works, the tableView works so is it the opening of the json file I saved from the response?
So am I doing something wrong when I read the contents of the json or when I save it?
I made a little change and moved the facebook.login() up and below the fbListener(event) and now it at least let me login to FB before the crash. If I now shut down the app and restart it, it works. I don't need to comment out the tableView etc anymore.
AARGH!!! this is driving me crazy!!!
Why would it not let me peacefully login to FB, get the json, and populate the darn tableView......
I wrote a little sample and tested it and it got to the FB login, auth and returned back to app and like you no content or tableView is rendered.
Then I checked the xcode console and found this error
1 | Feb 8 21:33:50 unknown UIKitApplication:se.creativefusion.fbtestapp[0xf573][28957] <Notice>: Lua Runtime Error: lua_pcall failed with status: 2, error message is: bad argument #1 to '?' (string expected, got nil) |
I assume, because of the crash after the successful FB login when it is supposed to decode the saved response that it has something to do with json. But like you said, the app runs fine if it's killed and re-started.
I'm using the latest build .741 and they changed to another json lib from what I understand. I'll get an older build and try it there instead.
Someone from ansca need to look into this issue.
I'll get back when I have some more info.
Be patient.
@lano78
Hey David
Remember we were trying this before, looks like you nailed it this time. Sorry I can't help you, I'm struggle myself with our first app. Hope you don't mind, I borrowed your code ( open json, populate tableview )for our fitness app.
Maybe I will add this facebook stuff too but it seems so difficult.
Cindy
Yeah, I had a break from this and tried other things until now. I really want this to work but I don't have clue what to do now.
This is so odd because of it auth with facebook and returns to the app but then the app freeze/stall/crash and I have to shut it down and restart and then it works fine with the statuses in the tableview.
I think this is so weird.
@David
I've been playing with facebook Api and graph this weekend and tried a bunch of different configurations on the facebook side with extended permissions. It seems like extended permissions mess things up and could be the reason for the crashes.
I created two appID's on facebook, first one with extended permissions and the second one was just plain with nothing extra.
The first one is the one I used when I got the error I posted above, the second one that I use now doesn't produce the error. So I think personally that what happened was that I skimmed through the facebook graph pages too quickly and missed the vital parts on what needs what.
So go back to FB and disable things you don't need because there's no point having them if you're not gonna use it. So do that and you'll see it will work for ya, if you have any question send me a tweet.
Take care
@lano78
Try changing :
to
You don't need to initialize it twice