Retail Evolved

Skip to Main Content »

Search Site
Home of the Original Facebook Like Button for Magento

You're currently on:

Facebook Updates OpenGraph Page Requirements

Tuesday, November 8, 2011 12:00:51 AM MST

You MUST update your <html> tags if you are using the XFBML button

Recently, we started to receive a number of support requests indicating that the Like button was not posting correct images and descriptions to user's walls. We started digging and discovered that Facebook quietly made a change to their documentation that will have a direct impact on you if you are using an XFBML button.

In the old version of our docs, it instructed you to change your opening <html> tag to:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" xmlns:fb="http://www.facebook.com/2008/fbml" xmlns:og="http://opengraph.org/schema/" lang="<?php echo $this->getLang() ?>"

Well, they changed it. Now you need to change it to read:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" xmlns:fb="http://www.facebook.com/2008/fbml" xmlns:og="http://ogp.me/ns#" lang="<?php echo $this->getLang() ?>"

Note the change to xmlns:og="http://ogp.me/ns#".

This change needs to be made to the following files:
  • app/design/frontend/[package]/[theme]/template/page/1column.phtml
  • app/design/frontend/[package]/[theme]/template/page/2columns-left.phtml
  • app/design/frontend/[package]/[theme]/template/page/2columns-right.phtml
  • app/design/frontend/[package]/[theme]/template/page/3columns.phtml
If you do not make this change, the button may not function as you expect it to. Once you are done making the change, you should run a few test URLs through the Facebook URL linter here: https://developers.facebook.com/tools/debug - it will tell you if there are any problems. You may get a warning about a locale, but that is an issue that will be addressed in a future update (don't worry, Facebook still grabs the locale from your web page).

   


0 Comments | Posted in Retailers Magento Developers By Alex Nielsen

Retail Needs a Simple Data Sharing Standard

Friday, May 28, 2010 8:24:21 AM MDT

Current data sharing solutions are expensive and complicated - so much so, that typically only the "big box" stores can participate. It's time to move away from complexity and embrace a simple data sharing standard for retail.

How it Could Save (and Earn!) Cash

Eliminates most manual data entry. Think about it: Much of the information you input into your system is created at the top of the supply-chain by the manufacturer. Descriptions, images, suggested pricing, UPC, manufacturer part number - just to name a few. If you buy direct, they even have your cost. A simple sharing standard would open this up to be used by distributors and retailers alike. Why should you enter data again if somebody has already done it for you?

Up-to-date information. Have you ever lost money because a supplier forgot to send you information about a cost increase? Mistakes happen, and some are more expensive than others. Maintaining pricing information in particular can be a tedious and difficult task. In my dream world of simple data sharing, my POS system will automatically get updated costs every night. When I get there in the morning, I will be presented with cost movements so that I can intelligently determine if I need to adjust my selling price. I know, it sounds like Minority Report style retail technology; but, this type of functionality would be commonplace if a standard were in place.

Your systems could talk to each other! Even the smallest operations will have multiple systems nowadays. It's not uncommon for a "mom and pop" to have a POS system, accounting software, and a website. Guess what? They *all* need some of the same data. As a standard gets adopted, software developers could build import / export functionality into everything they do. Wouldn't it be nice if inputting your data once caused it to cascade automatically to all of your systems?

Customers would love it! "What? Most customers couldn't care less about what my data looks like or how it gets there". That is, unless part of the standard enabled you to share live inventory information. Mobile, location-based services are huge right now. A customer could literally take their Christmas shopping list and find every store near them that has what they are looking for. What's more, since it is an open standard, developers could make all sorts of applications to utilize your data.

What it Should Look Like

Public property - no gatekeepers. No private organization should claim ownership of the standard. An organization could be created to administer the standard, but adopters shouldn't even have to be aware of this organization to start implementing it. Think HTML and websites. Did you have to call the W3C to start developing your website? Did you even know that they existed?

Simple. Yep, simple. Now, the term "simple" is relative. But standards like EDI and GS1 are way over the top. They try to provide rules for every possible scenario resulting in thick rulebooks and incomprehensible jargon. Here's an idea: Instead of trying to think of every possible scenario, make the standard flexible. Let participants find creative ways to solve problems and they will. Just look at how far the web has come!

Free. Access to the standard should be free (looking at you, ARTS). Adoption of the standard should not require an admission fee or annual dues. The only cost should be the cost of implementation. Again, like building a website.

Privacy and Access Controls. One difference between web sites and a retail standard is the need for privacy. Some information should not be available for public consumption (i.e. your cost). Participants must be able to determine who has access to what information.

0 Comments | Posted in Retailers Developers By Alex Nielsen

10 Things I Wish I Knew Before Making an iPhone App, Part 2

Sunday, January 10, 2010 1:13:47 PM MST

This is the second and final post about what I wish I knew when I started iPhone development. Last time, we spent a lot of time on memory management and some basic XCode and Objective-C tips. To wrap up, we’ll be focusing on dot notation, Instruments, and App Store tips.

6) Properties and Dot Notation

The concept of properties and dot notation is pretty familiar to developers. In fact, it is so second nature in many high level languages, that some developers may be surprised there’s a term for it.

Just in case you are one of those developers, dot notation is when you access an object’s attributes like so:

string myString = myObject.attribute;

or

myObject.attribute = 'new value';

As developers, we love that. It’s much simpler than using getters and setters (though, in thruth, that’s what is happening in the background).

Objective-C supports dot notation for accessing attributes. The usage is extremely straight forward when accessing the built-in classes. The confusion comes when you need to create your own properties to be accessed via dot notation (which I highly recommend).

Before I continue, please note that the following advice has worked for me very well. I’ve seen it implemented in lots of samples, but there are other ways to accomplish the same thing.

Creating a property is a three step process:

  1. In the header file of your class, define a local variable that begins with an underscore (the underscore is just good practice)
  2. In the header file of your class, define a property – the property name should be the same as the local variable, but without the underscore (again, for good practice)
  3. In the main file of your class, synthesize the property that was defined in the header file and associate it with the local variable

Let’s step through that with an example of a simple class. I’m going to make a Person class and give it a property called name. I know, your mind has just been blown. Stay with me, it gets better.

First in the header file (let’s call it Person.h), we define our local variable:

@interface Person : NSObject {
NSString *_name;
}

Next, define the property (still in the header file):

@interface Person : NSObject {
NSString *_name;
}

@property (nonatomic, retain) NSString *name;
@end

The @property keyword is used to declare a property. (nonatomic, retain) are further instructions regarding the generated property. I encourage you to look up the meaning of nonatomic (and the other options for this portion) on your own. That said, if you are dealing with properties of complex types, you will use (nonatomic, retain) 95% of the time.

The retain keyword is extremely important and can be the cause of much angst if you don’t understand it. This keyword will cause new assignments to the property to be automatically retained (don’t worry, it also automatically releases it’s prior assigned value). More on that later.

Lastly, in the main file (let’s say Person.m), you need to synthesize the newly declared property and associate it with the local variable:

#import "Person.h"

@implementation Person

@synthesize name = _name;

@end

Now, you may be wondering why I like to have my local variable and my property named differently. That has to do with my two rules for dealing with object attributes:

  1. When dealing with the attribute from inside of the class, DO NOT use dot notation
  2. When dealing with the attribute assignments from outside of the class, DO use dot notation, but DO NOT allocate, initialize, and assign a value in the same line

Why? It all goes back to that retain keyword from earlier. See if you can figure out why this is bad:

self.name = [[NSString alloc] initWithString:@"Alex"];

Figured it out? Here’s a clue: What is the retain count of self.name after executing the above line of code? It’s 2. 1 for the alloc and another because we used dot notation on a property that was declared with the retain keyword.

It is this behavior that results in examples from Apple that look like this:

self.name = [[NSString alloc] initWithString:@"Alex"];

[self.name release];

The first time I saw that, it made no sense – that is, until I leaked a bunch of memory because I didn’t understand dot notation in Objective-C.

To keep it clear in my mind, this is how I handle attribute assignments from inside of the class:

_name = [[NSString alloc] initWithString:@"Alex"];

The retain count after that line? 1. By using the local variable, I avoid all manner of confusion (and pestilence).

When outside of the class, I prefer to do this:

NSString *newName = [[NSString alloc] initWithString:@"Alex"];

myPerson.name = newName;

Yes, it’s an extra line of code vs. Apple’s method, but it requires me to be actively aware of the memory consequences of my actions.

7) Instruments

Don’t underestimate the power of Apple’s bundled Instruments. These are invaluable in detecting leaks, managing memory, monitoring activity, and much more. I could devote a post to each instrument, but instead I’ll focus on the two that I have found to be the most useful: Leaks and Object Allocations.

Leaks is pretty straight forward, it monitors your application for memory leaks. It is a good first line of defense against poor memory management – much like a compiler is a good way to detect syntax errors. But, just like a compiler, it can’t catch all of your mistakes.

To start the Leaks Instrument, simply select Run->Start With Performance Tool->Leaks from your project in Xcode. It actually also runs Object Allocations, but I’ll get more into that in a minute.

To use Leaks, select Leaks from the Instruments panel on the left. It will auto-detect leaks every 10 seconds, or you can change the interval or force it to check manually. If there are leaks, you’ll visually see an orange spike on the timeline where it occurred and you’ll also get a full list of the leaked objects and their types.

What type of leaks does this pick up? Any time a variable goes out of scope but it has not been released, Leaks can detect that. However, it will not detect a leak if the variable and the objects retaining it are in scope. This is why I like Object Allocations.

Object Allocations has saved me on a number of occasions where I kept running out of memory but was not showing any leaks. By using Object Allocations, I could quickly identify that a certain class of object was getting allocated and staying in memory without ever getting released every time a certain button was pushed.

The “# Net” column of Object allocations is particularly useful as it tells you how many instances are currently taking up memory. You can filter down the objects being displayed by using the search box in the bottom-right of Instruments.

8 ) App Store: Cater to Offline Users

I have a confession. I’ve had apps rejected… multiple times… for multiple reasons. Sometimes the reasons don’t make much sense in my opinion. In fact, in one instance a friend and I tag-teamed on an app that got rejected because of a policy that was “going to be published with the next OS upgrade”. Thanks, Apple.

One reason that made total sense to me was that I had failed to cater to offline users. In my testing, for some reason beyond my comprehension, I had assumed that all of the users would have internet access. This was a stupid assumption, I know. Your users may not be online for any number of reasons (one being that AT&T has notoriously bad service).

How do you cater to these users? It’s pretty simple: If your app has online content, detect if the user is online (see Apple’s “Reachability” app) and let your users know that a connection is required to access that feature of your application.

9) App Store: Release Dates

If you’re a relatively small shop like me, or your clients don’t have a huge advertising budget, some of the best advertising you get is in the first few days that your application is released.

During that period, your app is front page in the primary category you list in. If you screw up your release date, you stand to lose a lot of sales / downloads.

To do this right, make sure that when you first submit your app that you set your release date way in the future (I’m talking 6 months). Don’t underestimate the time it will take to get your app through the review process – it can be a while sometimes. To maximize the time on that front page, wait for the coveted approval e-mail from Apple and then set your release date to the next day.

10) App Store: Mind Your Trademarks

The App Store is a great distribution channel. It is also extremely easy for intellectual property trolls from huge companies to troll for the slightest infringement. Before you release an app, make sure that the name is not trademarked.

In one instance, I accidentally stepped on a legitimate trademark. After a threatening letter, I quickly changed the name of the app and no harm was done.

In another instance, it wasn’t quite so clean. See, I share a last name with a very prominent media company. I used to use my last name in my business name, but was threatened with law suits by said media company that I needed to change my name. Never mind that surnames cannot be trade marked – I simply couldn’t afford to defend against the huge budget of a media giant. So, I backed down.

My point is that they found me through the App Store. Technically, I was not in the wrong, but I could not afford to defend against their claim. Again, be careful with company and app names.

 

0 Comments | Posted in Developers By Alex Nielsen

MySQL GROUP_CONCAT Function

Monday, December 21, 2009 11:46:07 PM MST

I frequently jump between databases as lots of clients require data to be transferred between their old systems to their new systems. The two databases I work with most frequently are Microsoft SQL and MySQL. I like them both. In the constant battle for my devoted worship, MySQL wins today.

I’m currently working on a migration to Magento from a MySQL backed Rails site. When possible, I like to use Magento’s built-in import functionality due to its extremely complex table structure. I needed to get a comma-separated list of values representing the various images associated with a product.

The way it was in the original database was pretty straight forward – here’s a simplified version:

idproduct_idfilename
111a.jpg
211b.jpg

I needed to turn that into “1a.jpg;1b.jpg”. Now, in Microsoft SQL, you need to do some SQL acrobatics to make this happen (see this post). In MYSQL, this is cake:

SELECT product_id, GROUP_CONCAT(filename ORDER BY filename ASC SEPARATOR ';') AS 'filenames'
FROM product_images GROUP BY product_id

The results?

product_idfilenames
11a.jpg;1b.jpg

There’s nothing like a little simplicity.

0 Comments | Posted in Developers By Alex Nielsen

10 Things I Wish I Knew Before Making an iPhone App, Part 1

Sunday, December 20, 2009 11:30:43 PM MST

Creating your first iPhone app can be a challenging experience. For me, it made developing fun again, but only after coming to terms with some concepts that were strange to the Microsoft-wired, C# spewing machine that I call my brain.

1) Memory Management 101

You’ll see that a few of these points deal with memory management. It’s a potentially confusing concept to those of us who have never had to deal with it before. This single concept added probably 20 hours of mind-numbingly tedious debugging to my first app.

Most developers don’t have to worry about managing memory. C#, Java, PHP, Rails, and many more all manage memory for you. What does this even mean? It means that magical memory gnomes automatically “garbage collect” objects that aren’t needed any more. The iPhone SDK doesn’t offer this luxury – you get to play the role of garbage collector.

Let me tell you what will happen if you ignore this concept. Your app will be chugging along nicely until you start watching that embedded YouTube video of your grandma juggling chainsaws when suddenly…crash!

“No biggy”, you say, “I’ll just re-create it and pay close attention to the debugger. It will tell me what I need to do!” So, you start up your debugger, access the video, but nothing happens – it works as expected. “Must be a fluke”, you think to yourself. You continue testing, when …. crash! Out of the blue, the app crashes while testing your tilt-to-scroll functionality. Again, you attempt to re-create, but it’s a no go. Your debugger reads “EXC_BAD_ACCESS” – wow, thanks for the help.

This is a classic case of memory management gone bad. The unfortunate thing with that scenario is that it often won’t start happening until you start testing on devices (the iPhone Simulator is pretty tolerant of unreleased memory – lots more RAM to eat). And when it starts happening, it feels like the gnomes that you used to have working for you are now working against you. Plus, the debugger’s not much help – at least, it won’t tell you where the leaks are happening. You should know, however, that EXC_BAD_ACCESS indicates that you tried to access some memory that has already been released. This either happens because a) You released it and then attempted to access it again, or b) In an attempt to reclaim its quickly depleting memory, the iPhone OS started releasing your views (that’s the default behavior of a memory warning received by a controller).

I could write pages and pages regarding the finer points of memory management, but Apple already has here. You should (must, really) read the entirety of that document. It may sound a bit technical at first, but keep it handy. It will save you hours.

I’ll run down some of the basics as a bit of a primer:

  • Every object has a property called “retainCount” – this is the number of references that have been made in code to the address of your object. This is accessed via [myObject retainCount].
  • As long as this number is greater than 0, that memory stays reserved.
  • A retain count is increased when a “retain” message is sent or when an object is initially allocated.
  • The retain count is decreased by sending a “release” message to your object – [myObject release].
  • When the retain count hits 0, the “dealloc” method of the object gets called and the memory is released (assuming that the “dealloc” method does its job right).
  • A “leak” occurs when an object goes out of scope without being released. You now have no way of releasing that memory…. These are bad and are likely the cause of most major power outages (not really).

Here are some basic rules:

  • Every alloc needs a corresponding release. Make this second nature. Personally, I like to write in the release message at the same time as the alloc message so that I don’t forget. It’s kind of like opening and closing parentheses…
  • In your own class definitions, your dealloc method should release all of the objects it has references to. This includes properties and local variables.
  • When you add an object to an array or dictionary, release it before the original reference goes out of scope. Adding an object to an array or dictionary increases the retain count by 1. This makes sense – the array is taking ownership of the object and retains it so that it doesn’t lose the reference. Later on, when the array is released, all of its objects will be released with it.

So, be a responsible memory manager. It’s not that hard once you get the hang of it. At first, you just need to keep a close eye on your retain counts and use Instruments to help you identify leaks (more on that in a later post).

2) NSAutoReleasePool – Just When Memory Management Was Starting to Make Sense

The points we talked about in Memory Management 101 doesn’t apply 100% of the time. It only applies to objects that are explicitly retained or allocated. So, what happens to everything else? For example:

[NSString stringWithString:@"Hello World"]

There’s no alloc or retain message anywhere in sight, so we don’t have to release it. Yes! You’re off the hook right? Wrong (well, sort of).

See, when an object is created using a class method (as in the above example), it is assumed that the method adds the created object to the most recently created NSAutoReleasePool (on the current thread). “Wait a minute,” you may be thinking, “I didn’t create one of those”. You don’t have to. The application, by default, creates one NSAutoReleasePool on the main thread. When the application exits, it sends a release message to the NSAutoReleasePool, which in turn sends a release message to all of the objects in the pool. Pretty nifty, right?

Most of the time, it’s okay to let small objects such as strings get handled this way. Personally, I still prefer to explicitly allocate and release my strings, just to keep myself in the habit. When should you use NSAutoReleasePool explicitly?

  1. Any time you are performing an action on thread other than the main thread. Threads that get spun off (say, a selector that gets triggered by NSTimer), do not have access to the NSAutoReleasePool on the main thread. Objects that are sent the autorelease message are essentially leaked – there’s no pool to add them to. That is, unless you explicitly create one. Which you should. Just make sure you release it before the method is finished.
  2. Because you prefer to release your objects this way – it’s your style. There’s no problem with creating an NSAutoReleasePool at the beginning of a method and then releasing it before the method ends. In between you can have all manner of autoreleased objects, either because you told them to autorelease or because you used a convenient class method. Just make sure you don’t explicitly release an autoreleased object – you’ll pay later when you attempt to release NSAutoReleasePool.

3) [UIImage imageNamed:@"memoryHog.png"]

Chances are that you’ll need to work with images at some point in the course of your iPhone development. If so, you’ll likely look for the easiest way to grab an image from your application resources. [UIImage imageNamed:] is that method. It’s short, sweet, and you don’t have to figure out the path to your image. Programming bliss…. until you use this method to access a dozen high-res, full-screen images and your app starts crashing (I speak from painful experience).

This method is extremely convenient. And you should use it – sometimes. What isn’t immediately clear about this method is that it loads the image and then caches it in memory in case you need it again. The catch? You don’t have access to the cache where it’s stored – meaning you can’t purge it from memory. It stays there until the application is released.

What should you do instead? It depends, but this is usually a safe bet and gives you finer-tuned control over the release of the image:

UIImage *myImage = [[UIImage alloc] initWithContentsOfFile: @"path/to/my/file"];

The above isn’t a perfect example as you would want to get the path to your resource directory first, but I’ll leave that for you to discover for now. You could alter that method by tacking on an autorelease if you want to use an NSAutoReleasePool.

4) Alt+Double-Click = Enlightenment

Most of the time, SDK documentation is a twisted maze of technical writing. Apple has done a great job of making their documentation easy to access and surprisingly readable. To quickly access the documentation, simply use Alt+Double-Click on a method or class type from XCode.

The documentation will save you many hours of research. Refer to it. Often. If I were smart I would have used it to look up the implications of [UIImage imageNamed] before I learned the hard way.

5) NSLog, a Trusted Friend

In debugging, you will undoubtedly need to output something to the debugger at some point. You can use NSLog to do this. It’s particularly helpful for tracking retain counts and the like. Here’s a simple example:

NSLog(@"%d", [myObject retainCount]);

The first argument is a string format (which you should learn to love), and the following arguments are used to populate the formatted string.

Next Time…

That wraps up part one. Next time, we’ll take a look at instruments and some AppStore tips that will make your distribution easier.

0 Comments | Posted in Developers By Alex Nielsen
 

My Cart

You have no items in your shopping cart.

Newsletter

Newsletter