Friday, July 29, 2011

Viewing Native Text Input field in the Corona Simulator

Working with the native.newTextField() tonight and I needed a way to see the field in the simulator for easy positioning.  Out of the box this is not available within the Corona SDK simulator, but thanks to this post by Jon Beebe it got me thinking... Can we just "overload" the native.newTextField() method and Hi-Jack it when we are in the simulator and instead draw a rounded edge rectangle on the screen for the sake of viewing and positioning things?  Well, yes we can!



Let me walk you through it...  I threw a simple example together to demonstrate this. (I'll keep it as small as possible, you will also need the ui.lua file from Corona examples to run this example, the other two files you need are at the bottom of the post)

In the main.lua file we simply add a label and a text input field (which will not display in the simulator without requiring in the "hijacks.lua" file)

The magic is in overloading the native.newTextField) method to do something different when we are in the simulator, but I want it to behave as normal when running on a device.  Don't let the box.setTextColor declaration in the hijacks file scare you, this is just a placeholder basically because I happen to be setting the text color in my main.lua file for the text input field.  This declaration accommodates this working in simulator mode as well as a device build without me having to toggle things or comment out things, etc.  Of course, there's other tricks for capturing text input as this still won't do that, it's just for visual representation and positioning of things.  For my release build I will just comment out the requires("hijacks") line and away I go!


main.lua
<code>

require("hijacks")
local ui = require("ui")

local function init()

local g = display.newGroup()
local background = display.newRect(0,display.screenOriginY, display.contentWidth, display.contentHeight-display.screenOriginY)
background:setFillColor(111, 111, 255)

g:insert(background)

-- Handler for the native keyboard
   local fieldHandler = function( event )
-- Hide keyboard when the user clicks "Return" in this field
  if ( "submitted" == event.phase ) then
    native.setKeyboardFocus( nil )
  end
 end

local label = display.newText( "Location: ", 10, 252, native.systemFont, 18)
label:setTextColor(255,255,255)
g:insert(label)

-- A native text input field (requires XCode Simulator build or device build)
inputField = native.newTextField( 100, 252, 200, 24, fieldHandler )
inputField.font = native.newFont( native.systemFont, 20 )
inputField.text = "Papillion, NE" -- example of searchable location
inputField:setTextColor( 45, 45, 45 )
g:insert(inputField)

end

init()

</code>


hijacks.lua
<code>

module(..., package.seeall)

local priorNativeNewTextField = native.newTextField
native.newTextField = function(left, top, width, height, listener)

  local box
 
  if system.getInfo( "environment" ) == "simulator" then

     box = display.newRoundedRect(left, top, width, height, 12)
     box.setTextColor = function(...)
     end
  else
     box = priorNativeNewTextField(left, top, width, height, listener)
  end

  return box
end

</code>

Tuesday, July 12, 2011

Getting your Bundle ID correct for App Store Submission using Corona SDK

My first app submission got bounced back for one simple reason:

3.4: App names in iTunes Connect and as displayed on a device should be similar, so as not to cause confusion

This is a pretty easy thing to screw up so I attempted to document the correct way to align your App name and Bundle ID so you can avoid getting bounced back like I did...

Step 1 - iTunes Connect
As soon as you know the name of your next app, you should go create a new App ID in your iTunes connect account so you can get that name reserved.



In this example I gave it an App ID of "Cool App", choose how you want the App ID Prefix created and finally set the App ID Suffix to "com.domainname.coolapp"

App ID - this is how your App is going to be searched and displayed to users
App ID Prefix -  this gets generated for you based on your provisioning profile being used
App ID Suffix - reverse DNS pattern to further uniquely identify this application

Piece of cake, no go get your application created and ready to upload!

Once you have filled in the remaining information about your application and you are ready to upload it (complete this process in iTunes Connect and your app is "Waiting for Upload" you are ready to continue...


Step 2 - build.settings

Before creating our deployment build, we need to add a couple of entries into the build.settings file, based on the information we put into iTunes Connect above...

These entries assure that the .zip package that gets submitted by Corona will match up with the expectations of the iTunes Connect information.

Now we are ready to build our deployment package, on to the last step...

Step 3 - Corona

This step is a bit tricky to me, and admittedly I don't know if it is 100% correct, however it is working for me and generating expected result in the App Store and the display device so if you have a better way please let me know!



Notice that in this dialogue for "Application name" I entered the reverse DNS Bundle ID from the iTunes Connect data.

My guess is that what happens is that Corona builds the Bundle ID based on the "Application name:" field in this dialogue box.  When I attempted to put in the App ID Description (IE Common name) of "Cool App" you will get a deployment upload error from Corona stating that your package doesn't match anything that iTunes Connect is expecting from you (based on my example here), but I still ran into a scenario where my package name passed the check but I was missing the Display Name entry in the build.settings that we did above.   This ultimately gets you the 3.4 rejection.

That's how it worked for me, so I hope it helps you!   Also, if I have made an error of if you know of another way to configure this data please let me know, but this process successfully got my application through the review and onto the market with the correct names after first getting rejected for this reason...

And just to clarify, in this example the final .zip file that gets uploaded to iTunes Connect would be called com.domainname.coolapp.zip  NOT coolapp.zip

Don't let a poor package name get you rejected and sent back around the review cycle!

Good Luck

--Croisened










Monday, July 4, 2011

My Corona SDK Quick Reference Items

This is just a quick list of reminders and tips that I look at when working on a project...I have these printed out, scribbled and post-it noted all over my desk so i figured I would make this post and clean up my workspace along the way.  You might find them useful...or not. :)

Common Screen Resolutions (Portrait)
iPod Touch - 320x480
iPhone 3G - 320x480
iPhone 4G - 640x960
iPad - 768x1024
Droid Incredible - 480x800
Droid X - 480x854
Evo - 480x800
XOOM - 800x1280

Gestures to account for, or not:  Tap, Drag, Flick, Swipe, Double Tap, Pinch Open, Pinch Close, Touch and Hold, Shake

Apple recommended minimum tappable size of a UI item:  44x44 points

Icons needed to support an Apple and Android deployment - (Start at a 512x512 image size, because you are going to need this for app submission, make all these smaller ones from that so you don't end up with a blurry/stretched 512x512 when you are all done - or used SVG or vector of course)

  • Icon@2x.png (114x114)
  • Icon-72.png (72x72)
  • Icon-hdpi.png (72x72)
  • Icon.png (57x57)
  • Icon-mdpi.png (48x48)
  • Icon.ldpi.png (36x36)

Base config.lua file:  (This is my basis for supporting Dynamic Image Resolution )
application = 
{
content = 
width = 320,
height = 480, 
scale = "zoomStretch",
fps=60,
imageSuffix =
{
   ["@1x"] = 1.5,
["@2x"] = 2,
["@3x"] = 2.4,
}
}
}

Base build.settings file:

settings = 
{

    android =
    {
      versionCode = "1"
    },
        
orientation = 
{
default = "portrait",
supported = 
{
"portrait",
},
},
        iphone =
        {
                plist =
                {
                        UIPrerenderedIcon = true,
                        UIApplicationExitsOnSuspend = true,
                        CFBundleIconFile = "Icon.png",
CFBundleIconFiles = {
  "Icon.png", 
  "Icon@2x.png", 
  "Icon-72.png", 
},
                },
        }
}



Some optimization tips:

  1. Get Rid of Blurry Text For Good!
  2. Definitely evaluate Director 1.3 and see if it fits your needs! If it does throw Ricardo a few bucks, this is a great jump start to a project!
  3. More tips from base2solutions
  4. Check your FPS


Apple Human Interface Guidelines:
http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40006556-CH1-SW1

Android Guidelines:
http://developer.android.com/guide/topics/fundamentals.html

That's a start, this cleared a ton off my desk!  What do you have laying around?  Send me anything to add to this list or post your own...

Croisened

Saturday, July 2, 2011

99 Bottles

Ever wonder what you can do in a couple of weeks in the evenings with the Corona SDK?






I wanted to create a simple game so I chose to start with some of the great sample code provided on the Corona site.  In this case you will quickly recognize that I am using the Samarai Fruit sample as a foundation to my game, "99 Bottles"

99 Bottles is a very simple concept...a great place to start when picking up a new SDK to learn!

Break 99 blue bottles and you win.  The game gets progressively harder the closer you get to 99.


From the Intro screen you can choose to jump right in and play or view the rules...



It's easy!  Swipe a blue bottle and you get a point, hit a barrel and you get two!
No room for error though, if you hit a red bottle your game is over!
Also, if you skip a blue bottle you lose a point so you can't wait forever to make your move!

You get the idea, bottles flying all over the place and you trying to hit the blue ones.  Sorry for the poor quality video, its from my phone and what do you expect for a FREE game! :)

The game ends when you successfully break 99 blue bottles, or when you successfully break 1 red one!

At the end of the game you can compare against your all time best score as well as brag about your score to your Facebook wall to see if any of your friends can do any better!


I really want to say thanks to the Corona community as I have got so much from the forums and code examples.



This game is the initial game release for Fully Croisened, it will remain free and contain no ads, EVER.  If you like the game and want to see updates please Like the app and Fully Croisened on Facebook.

If we get to 5000 "likes", I will put out an update to this version that will include some new scoring features and other twists - if not, well, on to other projects until we get it right!

Hope you like it,
      Croisened