Business App Map Error

Hello Corona Comunity,

I made a Sports app and I used the Corona Business App as the basis for my app, thanks to this community and the great support my app is under review status at the iTunes Connect!

I am testing my and I use the Map, I took the example from the Corona business app.

Everything works fine, but during testing if I switch from map to another option, while the map still loading, using the tab bar sometimes I get this error: Runtime Error - Attempt to index up value “myMap” (a nil value)

when the map is trying to add markers on this line:

myMap:addMarker(event.latitude, event.longitude, options)

how can I avoid this to happen?

Without seeing your code, it’s going to be difficult to be specific, but before you call myMap:addMarker() you probably should test to make sure myMap exists.

if myMap then      myMap:addMarker( event.latitude, event.longitude, options ) end

Just speculating as to why myMap would go missing is since it’s a native object, you’re probably adding it when you go to the map scene and removing it when you’re leaving it. Your addMarker API may be getting called in a timer or call back listener somewhere.

Rob

Rob here is the code: 

local composer = require( "composer" ) local scene = composer.newScene() local widget = require( "widget" ) local widgetExtras = require( "widget-extras" ) local myApp = require( "myapp" ) widget.setTheme(myApp.theme) local titleText local myMap local locationtxt local mapWidth local mapHeight local navBar local addressGroup local addressLabel local addressField local views = {} local stadiumLocations = {} stadiumLocations[1] = "Saint Petersburg Stadium, Russia"--"1745 E Bayshore Rd, Palo Alto, CA" stadiumLocations[2] = "Fisht Stadium, Russia" stadiumLocations[3] = "Ekaterinburg Arena, Russia" stadiumLocations[4] = "Cosmos Arena, Russia" stadiumLocations[5] = "Kazan Arena, Russia" stadiumLocations[6] = "Nizhny Novgorod Stadium, Russia" stadiumLocations[7] = "Kaliningrad Stadium, Russia" stadiumLocations[8] = "Spartak Stadium, Russia" stadiumLocations[9] = "Kaliningrad Stadium, Russia" stadiumLocations[10] = "Rostov Arena, Russia" stadiumLocations[11] = "Volgograd Stadium, Russia" stadiumLocations[12] = "Mordovia Arena, Russia" local function ignoreTouch( event ) return true end local function markerListener( event ) print("type: ", event.type) -- event type print("markerId: ", event.markerId) -- id of the marker that was touched print("lat: ", event.latitude) -- latitude of the marker print("long: ", event.longitude) -- longitude of the marker end local function addStadiums( event , id ) local options = { title="Stadium", subtitle=stadiumLocations[id], imageFile = { filename = "images/stadiummarker@2x.png", baseDir = system.ResourcesDirectory }, listener=markerListener } myMap:addMarker(event.latitude, event.longitude, options) end local function mapLocationHandler(event) myMap:setCenter( event.latitude, event.longitude, false ) myMap:setRegion( event.latitude, event.longitude, 35.0, 35.0, false) --print("adding office marker") local options = { title="Luzhniki Stadium", subtitle="Moscow", imageFile = { filename = "images/stadiummarker@2x.png", baseDir = system.ResourcesDirectory }, listener=markerListener } result, errorMessage = myMap:addMarker( event.latitude, event.longitude, options ) if result then --print("everything went well") else print(errorMessage) end end local function setMode( event ) if event.phase == "ended" then for i = 1, #views do views[i]:setFillColor(0, 0, 1) views[i].label:setFillColor( 1, 1, 1 ) end views[event.target.index]:setFillColor( 0, 0, 0.85 ) views[event.target.index].label:setFillColor( 1, 1, 1 ) myMap.mapType = event.target.mode end return true end local function textFieldHandler( textField ) return function( event ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- In some cases you may want to adjust the interface when the keyboard appears. elseif ( "editing" == event.phase ) then elseif ( "submitted" == event.phase or "ended" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard --print( "Final Text: ", event.target.text) navBar:setLabel( event.target.text) myMap:requestLocation( event.target.text, mapLocationHandler ) -- Hide keyboard native.setKeyboardFocus( nil ) end end end function scene:create( event ) local sceneGroup = self.view local params = event.params local background = display.newRect(0,0,display.contentWidth, display.contentHeight) background:setFillColor( 0.95, 0.95, 0.95 ) background.x = display.contentWidth / 2 background.y = display.contentHeight / 2 sceneGroup:insert(background) navBar = widget.newNavigationBar({ title = params.pageTitle, backgroundColor = { 0, 0, 1 }, titleColor = {1, 1, 1}, font = myApp.fontBold }) sceneGroup:insert(navBar) addressGroup = display.newGroup() sceneGroup:insert( addressGroup ) local addressBackground = display.newRect( 0, 0, display.contentWidth, 30 ) addressGroup:insert( addressBackground ) addressBackground:setFillColor( 1 ) addressBackground.anchorX = 0 addressBackground.anchorY = 0 addressLabel = display.newText( "Address", 10, 15, myApp.fontBold, 20) addressLabel:setFillColor( 0 ) addressGroup:insert( addressLabel ) addressLabel.anchorX = 0 addressLabel.anchorY = 0.5 addressGroup.x = 0 addressGroup.y = navBar.y + navBar.height+30 -- -- This serves two purposes. First, its place holder so we can see where the mapView will be while -- working in the simulator. Secondly, it lets us have something to calculate the positions of the -- map's tabs before the map is created. -- mapWidth = display.contentWidth -- height of tabBar - height of the navBar - 20px for the buttons. mapHeight = display.contentHeight - 50 - navBar.height - 30 - 90 --(address field height defined later) local mapbox = display.newRect(0, 0, mapWidth, mapHeight) mapbox.x = display.contentCenterX mapbox.y = mapHeight / 2 + navBar.height + 30--30 -- (address field height) mapbox:setFillColor( 0.5, 0.5, 0.5 ) sceneGroup:insert(mapbox) local tabWidth = mapWidth / 3 views[1] = display.newRect(0,0,tabWidth,50) views[1].x = display.contentCenterX - tabWidth views[1].y = mapbox.y + (mapbox.height / 2)+50 views[1]:setFillColor( 0, 0, 0.85) views[1]:setStrokeColor( 0, 0, 1) views[1].strokeWidth = 3 views[1].label = display.newText("Standard",0,0,myApp.font, 18 ) views[1].label.x = views[1].x views[1].label.y = views[1].y - 3 views[1].label:setFillColor( 1, 1, 1 ) views[1].index = 1 views[1].mode = "standard" sceneGroup:insert(views[1]) sceneGroup:insert(views[1].label) views[2] = display.newRect(0,0,tabWidth,50) views[2].x = display.contentCenterX views[2].y = mapbox.y + (mapbox.height / 2) +50 views[2]:setFillColor( 0, 0, 1) views[2]:setStrokeColor(0, 0, 0.85 ) views[2].strokeWidth = 3 views[2].label = display.newText("Satellite",0,0,myApp.font, 18 ) views[2].label.x = views[2].x views[2].label.y = views[2].y - 3 views[2].label:setFillColor( 1, 1, 1 ) views[2].index = 2 views[2].mode = "satellite" sceneGroup:insert(views[2]) sceneGroup:insert(views[2].label) views[3] = display.newRect(0,0,tabWidth,50) views[3].x = display.contentCenterX + tabWidth views[3].y = mapbox.y + (mapbox.height / 2) +50 views[3]:setFillColor( 0, 0, 1) views[3]:setStrokeColor(0, 0, 0.85 ) views[3].strokeWidth = 3 views[3].label = display.newText("Hybrid",0,0,myApp.font, 18 ) views[3].label.x = views[3].x views[3].label.y = views[3].y - 3 views[3].label:setFillColor( 1, 1, 1) views[3].index = 3 views[3].mode = "hybrid" sceneGroup:insert(views[3]) sceneGroup:insert(views[3].label) end function scene:show( event ) local sceneGroup = self.view if event.phase == "did" then -- The text field's native peice starts hidden, we show it after we are on screen.on local fieldWidth = display.contentWidth - 120 addressField = native.newTextField( 110, addressLabel.y, fieldWidth, 30 ) addressField:addEventListener( "userInput", textFieldHandler( function() return addressField end ) ) addressGroup:insert( addressField) addressField.anchorX = 0 addressField.placeholder = "Address" -- -- Because mapViews's are native objects, the cannot intermix with the OpenGL objects that composer is -- managing. It's best to create it here and destory it in exitScene. myMap = native.newMapView( 0, 0, mapWidth , mapHeight ) if myMap then myMap.mapType = "standard" -- other mapType options are "satellite" or "hybrid" -- The MapView is just another Corona display object, and can be moved or rotated, etc. myMap.x = display.contentCenterX myMap.y = mapHeight / 2 + navBar.height + 30 -- -- Let's add some additional points of interest around our location -- -- The event structure returned by requestLocation doesn't contain a reference to the data that -- can be used to look up information to populate the marker's bubble or pass on to a more complex information -- system (phone number, URL, etc.) -- -- Let's use a Lua Closure (anonymous function) that will take the event table returned by the call and then -- call our real function using the index of the table as an ID for the marker -- for i = 1, #stadiumLocations do myMap:requestLocation(stadiumLocations[i], function(event) addStadiums(event, i); end) end myMap:requestLocation("Luzhniki Stadium, Russia",mapLocationHandler) views[1]:addEventListener("touch", setMode) views[2]:addEventListener("touch", setMode) views[3]:addEventListener("touch", setMode) --native.setActivityIndicator(false) else native.showAlert( "Simulator", "Maps are only avaiable on device.", { "Okay" } ) end end end function removeMap() --print ("removing Map") if myMap and myMap.removeSelf then myMap:removeSelf() myMap = nil end end function scene:hide( event ) local sceneGroup = self.view -- -- Clean up native objects -- --if event.phase == "will" then if event.phase == "did" then -- remove the addressField since it contains a native object. addressField:removeSelf() addressField = nil -- remove the map since it's a native object. timer.performWithDelay( 300, removeMap ) --[[if myMap and myMap.removeSelf then myMap:removeSelf() myMap = nil end]]-- end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

It’s likely this code:

 for i = 1, #stadiumLocations do myMap:requestLocation(stadiumLocations[i], function(event) addStadiums(event, i); end) end

You probably should test to make sure myMap exists before you call addStadiums (or at least put the code inside addStadiums)

Rob

Rob,

Before the For loop there is a check 

if myMap then .... for loop end

is that what you mean?

No.  The request for an address takes time so it has a call back listener function that gets called once the data is available. If you’ve changed scenes and myMap gets removed, then that call back function fires but doesn’t have a map object to add the marker too.

I was thinking something like:

 for i = 1, #stadiumLocations do myMap:requestLocation(stadiumLocations[i], function(event) if myMap then addStadiums(event, i); end end) end

or something like that.

I just tried the above, but the same error happens.

Robert, I was able to fix it , there were other locations that I needed to do the check.

Now when I test the same code on an Android Device (Samsung Galaxy S6) I get this invalid latitude argument error:

SM-G920V: ERROR: Runtime error

May 09 10:24:58.521 SM-G920V: venues.lua:69: Function mapView:addMarker() was given an invalid ‘latitude’ argument. Was expecting a number.

                    SM-G920V: stack traceback:

                    SM-G920V: [C]: ?

                    SM-G920V: [C]: in function ‘addMarker’

                    SM-G920V: venues.lua:69: in function ‘addStadiums’

                    SM-G920V: /Users/aroldocarvalho/Docu

May 09 10:24:58.534 ments/_Corona/2018WorldCup/venues.lua:270: in function <venues.lua:270>

Sounds like the requestLocation() API was unable to find one of your locations. You should also test the event.isError value to make sure it was successful. See:  https://docs.coronalabs.com/api/event/mapLocation/index.html and https://docs.coronalabs.com/api/event/mapLocation/isError.html.

You can print out the reason why it failed (example in the last URL above) and see why it’s failing.

Rob

Robert, there are 12 locations, and they all work fine on iOS, but for some reason they don’t work on Android.

Latitude is returning nil and so when I they to print the reason the code fails because it is nil.  

I also made sure that the build.settings included these:

android = { usesPermissions = { -- Required by the MapView to fetch its contents from the Google Maps servers. "android.permission.INTERNET", -- Optional permission used to display current location via the GPS. "android.permission.ACCESS\_FINE\_LOCATION", -- Optional permission used to display current location via WiFi or cellular service. "android.permission.ACCESS\_COARSE\_LOCATION", "com.google.android.c2dm.permission.RECEIVE", }, usesFeatures = { -- If you set permissions "ACCESS\_FINE\_LOCATION" and "ACCESS\_COARSE\_LOCATION" above, -- then you may want to set up your app to not require location services as follows. -- Otherwise, devices that do not have location sevices (such as a GPS) will be unable -- to purchase this app in the app store. { name = "android.hardware.location", required = false }, { name = "android.hardware.location.gps", required = false }, { name = "android.hardware.location.network", required = false }, }, },

Can you post the relevant code for your handler with the print statement and copy/paste your console log from your Android device?

Rob

Here is the code:

local function mapLocationHandler(event) if event.isError then print( "Error: " .. event.errorMessage ) else print( "The specified string is at: " .. event.latitude .. ", " .. event.longitude ) end if myMap~=nil then myMap:setCenter( event.latitude, event.longitude, false ) myMap:setRegion( event.latitude, event.longitude, 35.0, 35.0, false) --print("adding office marker") local options = { title="Luzhniki Stadium", subtitle="Moscow", imageFile = { filename = "images/stadiummarker.png", baseDir = system.ResourcesDirectory }, listener = markerListener } result, errorMessage = myMap:addMarker( event.latitude, event.longitude, options ) if result then --print("everything went well") else print(errorMessage) end end end

Something is wrong about the way that Android is handling the MapView, if I minimize the app after the error and them bring it up again I can see it plotting the map markers on the screen behind the error. here is a screenshot with a nil error

You can’t use the “…” operator to build one long string out of other values if one of those values is nil.  I don’t know if this is the guilty line of code or not, but I’ll use it as an example:

print( "The specified string is at: " .. event.latitude .. ", " .. event.longitude )

Instead you need to:

print( "The specified string is at: ", event.latitude, ", ", event.longitude )

This of course won’t look that pretty since the comma’s turn into tabs, but it won’t error. Look at venues.lua line 283 and see where you’re using a variable called “longitude” and figure out why it’s nil.

Rob

Rob I did that, and the log from the Corona emulator, runing on the Samsung device is below.

The latitude and longitude is nil, but the “event.isError” is returning FALSE, it sounds like the “myMap:requestLocation” is returning empty. 

Since my app plots 12 map markers, I decided to plot only one. When I do that some times it plots one and some time it gives the nil error. For some reason the requestLocation on Android needs more time to find the location.

I am using the device connected to the WiFi.

The next step will be to pass the Latitude and Longitude numbers and not use the myMap:request.

This is either a bug or some build.settings parameters. I am not sure.

Here are the locations I am using:

stadiumLocations[1] = "Saint Petersburg Stadium,Russia, 197110" stadiumLocations[2] = "Fisht Stadium,Russia, 354340" stadiumLocations[3] = "Ekaterinburg Arena, Russia, 620028" stadiumLocations[4] = "Kazan Arena,Russia, 421001" stadiumLocations[5] = "Nizhny Novgorod Stadium, Russia, 603159" stadiumLocations[6] = "Kaliningrad Stadium, Russia, 236006" stadiumLocations[7] = "Spartak Stadium, Russia, 125424" stadiumLocations[8] = "Samara Arena, Russia, 443072" stadiumLocations[9] = "Rostov Arena, Russia, 344002" stadiumLocations[10] = "Volgograd Arena, Russia, 400005" stadiumLocations[11] = "Mordovia Arena, Russia, 430009"

On the iPhone they work fine and if I paste the locations on google map it finds all of them too.

SM-G920V: The specified string is at: nil , nil May 09 06:15:04.407 SM-G920V: The spe May 09 06:15:04.407 cified string is at: nil , nil SM-G920V: The specified string is at: nil , nil SM-G920V: The specified string is at: nil , nil SM-G920V: The specified string is at: nil , nil SM-G920V: The specified string is at: nil , nil May 09 06:15:04.410 SM-G920V: The specified string i May 09 06:15:04.411 s at: nil , nil May 09 06:15:04.411 SM-G920V: The specified string is at: nil , nil May 09 06:15:04.413 SM-G920V May 09 06:15:04.414 : The specified string is at: nil , nil May 09 06:15:04.415 SM-G920 May 09 06:15:04.416 V: The specified string is at: nil , nil May 09 06:15:04.431 SM-G920V: T May 09 06:15:04.431 he specified string is at: nil , nil SM-G920V: The specified string is at: nil , nil May 09 06:15:06.667 SM-G920V: ERROR: May 09 06:15:06.667 May 09 06:15:06.672 Runtime error May 09 06:15:06.672 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \< May 09 06:15:06.676 venues.lua:286\> May 09 06:15:06.676 SM-G920V: ERROR: Runtime error May 09 06:15:06.676 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: ? SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.698 SM-G920V: ERROR: Runtime error May 09 06:15:06.698 SM-G920V: /Users/aroldocarvalho/Documents/\_Corona/201 May 09 06:15:06.700 8WorldCup/venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.701 SM-G920V: ERROR: Runtime error May 09 06:15:06.701 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: ? SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.701 SM-G920V: ERROR: Runtime error May 09 06:15:06.701 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.701 SM-G920V: ERROR: Runtime error May 09 06:15:06.701 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: ? SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.731 SM-G92 May 09 06:15:06.732 0V: ERROR: Runtime error May 09 06:15:06.732 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.732 SM-G920V: ERROR: Runtime error May 09 06:15:06.732 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: ? SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> SM-G920V: Loc Handler Error: May 09 06:15:06.732 SM-G920V: ERROR: Runtime error May 09 06:15:06.733 SM-G920V: venues.lua:85: Function mapView:setCenter() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: in function 'setCenter' SM-G920V: venues.lua:85: in function \<venues.lua:78\> May 09 06:15:06.733 SM-G920V: ERROR: Runtime error May 09 06:15:06.733 SM-G920V: venues.lua:85: Function mapView:setCenter() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: ? SM-G920V: [C]: in function 'setCenter' SM-G920V: venues.lua:85: in function \<venues.lua:78\> May 09 06:15:06.733 SM-G920V: ERROR: Runtime error May 09 06:15:06.733 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.733 SM-G920V: ERROR: Runtime error May 09 06:15:06.733 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: ? SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.733 SM-G920V: ERROR: Runtime error May 09 06:15:06.734 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\> May 09 06:15:06.734 SM-G920V: ERROR: Runtime error May 09 06:15:06.734 SM-G920V: venues.lua:74: Function mapView:addMarker() was given an invalid 'latitude' argument. Was expecting a number. SM-G920V: stack traceback: SM-G920V: [C]: ? SM-G920V: [C]: in function 'addMarker' SM-G920V: venues.lua:74: in function 'addStadiums' SM-G920V: venues.lua:286: in function \<venues.lua:286\>

Without seeing your code, it’s going to be difficult to be specific, but before you call myMap:addMarker() you probably should test to make sure myMap exists.

if myMap then &nbsp; &nbsp; &nbsp;myMap:addMarker( event.latitude, event.longitude, options ) end

Just speculating as to why myMap would go missing is since it’s a native object, you’re probably adding it when you go to the map scene and removing it when you’re leaving it. Your addMarker API may be getting called in a timer or call back listener somewhere.

Rob

Rob here is the code: 

local composer = require( "composer" ) local scene = composer.newScene() local widget = require( "widget" ) local widgetExtras = require( "widget-extras" ) local myApp = require( "myapp" ) widget.setTheme(myApp.theme) local titleText local myMap local locationtxt local mapWidth local mapHeight local navBar local addressGroup local addressLabel local addressField local views = {} local stadiumLocations = {} stadiumLocations[1] = "Saint Petersburg Stadium, Russia"--"1745 E Bayshore Rd, Palo Alto, CA" stadiumLocations[2] = "Fisht Stadium, Russia" stadiumLocations[3] = "Ekaterinburg Arena, Russia" stadiumLocations[4] = "Cosmos Arena, Russia" stadiumLocations[5] = "Kazan Arena, Russia" stadiumLocations[6] = "Nizhny Novgorod Stadium, Russia" stadiumLocations[7] = "Kaliningrad Stadium, Russia" stadiumLocations[8] = "Spartak Stadium, Russia" stadiumLocations[9] = "Kaliningrad Stadium, Russia" stadiumLocations[10] = "Rostov Arena, Russia" stadiumLocations[11] = "Volgograd Stadium, Russia" stadiumLocations[12] = "Mordovia Arena, Russia" local function ignoreTouch( event ) return true end local function markerListener( event ) print("type: ", event.type) -- event type print("markerId: ", event.markerId) -- id of the marker that was touched print("lat: ", event.latitude) -- latitude of the marker print("long: ", event.longitude) -- longitude of the marker end local function addStadiums( event , id ) local options = { title="Stadium", subtitle=stadiumLocations[id], imageFile = { filename = "images/stadiummarker@2x.png", baseDir = system.ResourcesDirectory }, listener=markerListener } myMap:addMarker(event.latitude, event.longitude, options) end local function mapLocationHandler(event) myMap:setCenter( event.latitude, event.longitude, false ) myMap:setRegion( event.latitude, event.longitude, 35.0, 35.0, false) --print("adding office marker") local options = { title="Luzhniki Stadium", subtitle="Moscow", imageFile = { filename = "images/stadiummarker@2x.png", baseDir = system.ResourcesDirectory }, listener=markerListener } result, errorMessage = myMap:addMarker( event.latitude, event.longitude, options ) if result then --print("everything went well") else print(errorMessage) end end local function setMode( event ) if event.phase == "ended" then for i = 1, #views do views[i]:setFillColor(0, 0, 1) views[i].label:setFillColor( 1, 1, 1 ) end views[event.target.index]:setFillColor( 0, 0, 0.85 ) views[event.target.index].label:setFillColor( 1, 1, 1 ) myMap.mapType = event.target.mode end return true end local function textFieldHandler( textField ) return function( event ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- In some cases you may want to adjust the interface when the keyboard appears. elseif ( "editing" == event.phase ) then elseif ( "submitted" == event.phase or "ended" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard --print( "Final Text: ", event.target.text) navBar:setLabel( event.target.text) myMap:requestLocation( event.target.text, mapLocationHandler ) -- Hide keyboard native.setKeyboardFocus( nil ) end end end function scene:create( event ) local sceneGroup = self.view local params = event.params local background = display.newRect(0,0,display.contentWidth, display.contentHeight) background:setFillColor( 0.95, 0.95, 0.95 ) background.x = display.contentWidth / 2 background.y = display.contentHeight / 2 sceneGroup:insert(background) navBar = widget.newNavigationBar({ title = params.pageTitle, backgroundColor = { 0, 0, 1 }, titleColor = {1, 1, 1}, font = myApp.fontBold }) sceneGroup:insert(navBar) addressGroup = display.newGroup() sceneGroup:insert( addressGroup ) local addressBackground = display.newRect( 0, 0, display.contentWidth, 30 ) addressGroup:insert( addressBackground ) addressBackground:setFillColor( 1 ) addressBackground.anchorX = 0 addressBackground.anchorY = 0 addressLabel = display.newText( "Address", 10, 15, myApp.fontBold, 20) addressLabel:setFillColor( 0 ) addressGroup:insert( addressLabel ) addressLabel.anchorX = 0 addressLabel.anchorY = 0.5 addressGroup.x = 0 addressGroup.y = navBar.y + navBar.height+30 -- -- This serves two purposes. First, its place holder so we can see where the mapView will be while -- working in the simulator. Secondly, it lets us have something to calculate the positions of the -- map's tabs before the map is created. -- mapWidth = display.contentWidth -- height of tabBar - height of the navBar - 20px for the buttons. mapHeight = display.contentHeight - 50 - navBar.height - 30 - 90 --(address field height defined later) local mapbox = display.newRect(0, 0, mapWidth, mapHeight) mapbox.x = display.contentCenterX mapbox.y = mapHeight / 2 + navBar.height + 30--30 -- (address field height) mapbox:setFillColor( 0.5, 0.5, 0.5 ) sceneGroup:insert(mapbox) local tabWidth = mapWidth / 3 views[1] = display.newRect(0,0,tabWidth,50) views[1].x = display.contentCenterX - tabWidth views[1].y = mapbox.y + (mapbox.height / 2)+50 views[1]:setFillColor( 0, 0, 0.85) views[1]:setStrokeColor( 0, 0, 1) views[1].strokeWidth = 3 views[1].label = display.newText("Standard",0,0,myApp.font, 18 ) views[1].label.x = views[1].x views[1].label.y = views[1].y - 3 views[1].label:setFillColor( 1, 1, 1 ) views[1].index = 1 views[1].mode = "standard" sceneGroup:insert(views[1]) sceneGroup:insert(views[1].label) views[2] = display.newRect(0,0,tabWidth,50) views[2].x = display.contentCenterX views[2].y = mapbox.y + (mapbox.height / 2) +50 views[2]:setFillColor( 0, 0, 1) views[2]:setStrokeColor(0, 0, 0.85 ) views[2].strokeWidth = 3 views[2].label = display.newText("Satellite",0,0,myApp.font, 18 ) views[2].label.x = views[2].x views[2].label.y = views[2].y - 3 views[2].label:setFillColor( 1, 1, 1 ) views[2].index = 2 views[2].mode = "satellite" sceneGroup:insert(views[2]) sceneGroup:insert(views[2].label) views[3] = display.newRect(0,0,tabWidth,50) views[3].x = display.contentCenterX + tabWidth views[3].y = mapbox.y + (mapbox.height / 2) +50 views[3]:setFillColor( 0, 0, 1) views[3]:setStrokeColor(0, 0, 0.85 ) views[3].strokeWidth = 3 views[3].label = display.newText("Hybrid",0,0,myApp.font, 18 ) views[3].label.x = views[3].x views[3].label.y = views[3].y - 3 views[3].label:setFillColor( 1, 1, 1) views[3].index = 3 views[3].mode = "hybrid" sceneGroup:insert(views[3]) sceneGroup:insert(views[3].label) end function scene:show( event ) local sceneGroup = self.view if event.phase == "did" then -- The text field's native peice starts hidden, we show it after we are on screen.on local fieldWidth = display.contentWidth - 120 addressField = native.newTextField( 110, addressLabel.y, fieldWidth, 30 ) addressField:addEventListener( "userInput", textFieldHandler( function() return addressField end ) ) addressGroup:insert( addressField) addressField.anchorX = 0 addressField.placeholder = "Address" -- -- Because mapViews's are native objects, the cannot intermix with the OpenGL objects that composer is -- managing. It's best to create it here and destory it in exitScene. myMap = native.newMapView( 0, 0, mapWidth , mapHeight ) if myMap then myMap.mapType = "standard" -- other mapType options are "satellite" or "hybrid" -- The MapView is just another Corona display object, and can be moved or rotated, etc. myMap.x = display.contentCenterX myMap.y = mapHeight / 2 + navBar.height + 30 -- -- Let's add some additional points of interest around our location -- -- The event structure returned by requestLocation doesn't contain a reference to the data that -- can be used to look up information to populate the marker's bubble or pass on to a more complex information -- system (phone number, URL, etc.) -- -- Let's use a Lua Closure (anonymous function) that will take the event table returned by the call and then -- call our real function using the index of the table as an ID for the marker -- for i = 1, #stadiumLocations do myMap:requestLocation(stadiumLocations[i], function(event) addStadiums(event, i); end) end myMap:requestLocation("Luzhniki Stadium, Russia",mapLocationHandler) views[1]:addEventListener("touch", setMode) views[2]:addEventListener("touch", setMode) views[3]:addEventListener("touch", setMode) --native.setActivityIndicator(false) else native.showAlert( "Simulator", "Maps are only avaiable on device.", { "Okay" } ) end end end function removeMap() --print ("removing Map") if myMap and myMap.removeSelf then myMap:removeSelf() myMap = nil end end function scene:hide( event ) local sceneGroup = self.view -- -- Clean up native objects -- --if event.phase == "will" then if event.phase == "did" then -- remove the addressField since it contains a native object. addressField:removeSelf() addressField = nil -- remove the map since it's a native object. timer.performWithDelay( 300, removeMap ) --[[if myMap and myMap.removeSelf then myMap:removeSelf() myMap = nil end]]-- end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

It’s likely this code:

 for i = 1, #stadiumLocations do myMap:requestLocation(stadiumLocations[i], function(event) addStadiums(event, i); end) end

You probably should test to make sure myMap exists before you call addStadiums (or at least put the code inside addStadiums)

Rob

Rob,

Before the For loop there is a check 

if myMap then .... for loop end

is that what you mean?