Why would you use Interface Builder for iPhone Development?

Why would you use Interface Builder for iPhone Development?

I don’t understand why you’d use Interface Builder to create a UI for an iPhone application.

When I started building my first iPhone application at Shine, my colleagues advised me to avoid using Interface Builder. They’d tried using it when they were first starting out, but found that it just got in the way and made the learning curve steeper than it needed to be.

The problem for me was that many of the available books and tutorials for iPhone development used Interface Builder. Many of the sample apps on Apple’s site use it as well. I was having trouble figuring out how to not use it, so I took a deep breath and gave it a go.

I got confused pretty quickly. After thrashing around for a day or so, a colleague took pity on me and showed me how to bootstrap an iPhone user interface in code. I ditched Interface Builder and never looked back.

Sure, I probably would have figured it out, but why make life harder than it needs to be? As a new iPhone developer, I was already trying to get my head around Objective-C, Cocoa and XCode. Why add Interface Builder and NIB files to the list, for very little apparent benefit?

My Theory

Perhaps all the iPhone books and tutorials have been written by people who already had experience developing with Interface Builder and Nibs for Mac OS X.

Don’t get me wrong – I don’t have a problem with Interface Builder. It’s just that I wonder whether Interface Builder is more suited to it’s original purpose: building complex user interfaces that are to be used on a desktop computer.

iPhone applications, on the other hand, have a very limited set of widgets and layouts to choose from. Furthermore, there’s a limited amount of stuff you should put on a single screen.

Consequently it seems like overkill to crack out Interface Builder for an iPhone application.

More controversially, in my experience with GUI builders I’ve found that as soon as you try and build anything non-trivial, you’re going to have to code it by hand anyway. Furthermore, if an interface is so simple that you could build it with a GUI builder, I’ve found that it’s probably quicker to code it yourself. I’m not sure that Interface Builder is any exception to this observation.

To support these assertions, I’d like to point out that one of the more complex (and useful) sample iPhone applications that Apple provide – ‘TheElements‘ (which navigates the periodic table) – doesn’t use NIB files.

How to do it

So how does one bootstrap an iPhone interface without a NIB file? It turns out that it’s very easy to do, but there aren’t many examples out there on how to do it. So for the sake of knowledge-dissemination, here’s how you write a main.c that does it:

#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"MyAppDelegate");
    [pool release];
    return retVal;
}

The key part is that you provide the name of the AppDelegate you want to use to the UIApplicationMain method, instead of leaving it as nil.

You’d then just code your AppDelegate to bootstrap the UI however you see fit:

#import "MyAppDelegate.h"

@implementation MyAppDelegate

- (void)applicationDidFinishLaunching:(UIApplication *)application {
	UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	...
              Setup your controllers and views in here.
        ...
	[window addSubview:myViews];
	[window makeKeyAndVisible];
}

Finally, remove the property with the key ‘Main nib file base name’ (the raw key name is ‘NSMainNibFile’) from your Info.plist file.

What do you think?

Of course, as a newby to iPhone development, perhaps I’m missing something here.
If you’re new to iPhone development, have you found Interface Builder useful? If so, I’d like to hear about it. I can only speak from my own experiences (and those of my colleagues), so would be interested in hearing about the experiences of others.

ben.teese@shinesolutions.com

I'm a Senior Consultant at Shine Solutions.

44 Comments
  • Pingback:iPhone Tipps » Blog Archive » Why would you use Interface Builder for iPhone Development …
    Posted at 15:55h, 15 July Reply

    […] Ben Teese placed an observative post today on Why would you use Interface Builder for iPhone Development …Here’s a quick excerptI don’t understand why you’d use Interface Builder to create a UI for an iPhone application. When I started building my first iPhone application at Shine, my. […]

  • Chris
    Posted at 18:39h, 01 September Reply

    Hi Ben,
    I am also new to iPhone development. I am also having the same question, though.
    My first book to iPhone development is “iPhone SDK Application Development”. The codes inside were written without using any Interface Builder.
    However, I am also trying to see apps source code from the net. When it uses the interface builder for building the interface, I can not see the corresponding code for the UI part inside and it makes things become harder…

  • Murali
    Posted at 14:29h, 09 September Reply

    Hi Ben,
    I am working in iPhone from its first release, also have some 3 yrs of exp in MAC. When SDK is launched there is no concept called IB. So we used to create everything by code. But when it came it was full of bugs, being a MAC developers we are desperate for IB in iPhone. The main advantage of the IB is One can place the UI elements very easily in the right positions a live preview of the view how it looks. Also using IB gives a wonderful support for Localization. You can reduce the codings. But this completely depends on the requirements. My Idea is analyze which one needs to be done in Code and using IB. You may feel IB is not good because of that you are newbie, But as per my knowledge IB is excellent tool with good features to those know how to use it.

  • Anthony
    Posted at 19:29h, 11 September Reply

    I think the whole point of using IB is keeping your design and code seperate, which is supposed to be the “best practice”.

    I’m also just starting to learn programming for the iphone and am getting confused with all these links and things in IB, which I seem to break very easily, I’m considering scrapping using IB at all and just coding everything, especially since there’s quite a few things I want to program that the standard controls won’t support.

  • Patrick
    Posted at 18:40h, 19 October Reply

    Thank you thank you!

    I was ready to send a hired killer to the Interface Builder developer 🙂

    Your post finally got my View to display what I wanted it too 🙂

  • ronald
    Posted at 16:50h, 30 October Reply

    “I don’t understand why you’d use Interface Builder to create a UI for an iPhone application.”

    Really, don’t you understand or don’t you want to understand? There are different ways to do things and you don’t understand why somebody would want to do something different than how you (the master-expert on everything) do it?

    It’s called choice. Learn to live with it.

    • Rooz
      Posted at 07:07h, 01 June Reply

      Someones butthurt. This is programming, not fundamental political/social ideology. Your allowed to have different opinions.

  • Vic
    Posted at 17:04h, 05 December Reply

    Ron, I don’t think this article is “dissing” those who use IB, it is just expressing confusion as to why one would want to use it. I share that confusion, not because I’m a master-expert on everything, but because it seems like every time I try to use IB it bites me in the ass and I have to re-do things in code anyway. I’d genuinely love to know why IB is good, and how to use it without developing a sore bum. Doing things in code just may be more comfortable for some of us.

    It’s called choice. Learn to live with it. (Woah, dejavu… Where did I read that before? Must have been a glitch in the Matrix.)

  • Marvo
    Posted at 19:24h, 06 December Reply

    This article was exactly what I was hoping to find, but my heart sank when I read “Setup your controllers and views in here”! I don’t know how to do that part, either! I’d love to see a simple Hello World-ish full example, though I know it’s a lot to ask. (Or perhaps a pointer to such a thing?)

  • Anonymous
    Posted at 02:35h, 31 December Reply

    Anybody know why the Class Actions and Class Outlets pulldown is no longer available in the Identity inspector?

  • Anonymous
    Posted at 02:42h, 31 December Reply

    Never mind, found in release notes…

  • Brent
    Posted at 07:00h, 11 January Reply

    Being a new iPhone developer, I only used IB thinking it was a requirement to build an application. As my project progressed(particularly knowledge of ObjC/Cocoa) I eventually stopped using it.

    Sadly, I think Microsoft Visual Studio has a good implementation of separating code from view and connecting them easily.

  • Greg
    Posted at 21:29h, 17 January Reply

    “Sadly, I think Microsoft Visual Studio has a good implementation of separating code from view and connecting them easily.”

    It *is* sad that you think that. Snarkiness aside, I’ve used Xcode and VS extensively and from my standpoint VS’ technique includes some really unfortunate side-effects that I’ve had to code around too many times.

    It’s worth it to learn how to use IB the “right way.” It will reduce the amount of code you need to write (and thus support) and greatly simplifies localization. One of the key benefits to using IB is that the objects you create and store in nib files aren’t re-created at runtime by running the same lines of code you’d use to manually create and configure the objects. They’re stored in the nib file as archived, fully-constructed objects. This means that unlike coding by hand (and what Visual Studio does, which has the same result) you don’t have to worry about the side-effects of setters that may or may not be invoked during configuration.

    I seriously suggest that anyone who finds themselves writing more code when using IB than when not, as some writers have indicated, really needs to take a step back and ask themselves what they’re doing wrong. Because, simply put, they almost certainly are.

  • Cameron
    Posted at 19:36h, 19 January Reply

    As Greg said, the real benefit to using Interface Builder is that it reduces (hopefully) the amount of code you need to write, since it lets you avoid the tedium of initializing views (and other objects) and setting their attributes. There is a learning curve involved, but if you can get used to the way it works, it can be a valuable timesaver.

  • RobG
    Posted at 18:26h, 10 March Reply

    I have to say that Interface Builder’s UI implementation really belongs in the 20th century. A nib (or xib, as it’s now labeled), at design time, is simply a coded XML file that describes your application’s various objects. A programmer needs to use the Interface Builder to manipulate the nib, along with XCode to round out an application. You are therefore programming not in one, but two syntaxes. Objective-C, which is visible and XML, which is invisible.

    I hoped that Apple would have seen the light by now and tightly bound the two. Changing something in one tool automatically updates your work in the other – is that so hard? I can create my UI in Interface Builder, but I still need to manually create methods and implement events. Because you have to do that, you can’t really tell what’s connected and what’s not. With VS, I have a neat list of every method and event attached to my screen objects. If I miss something, I can easily see what’s missed and fix it. Likewise, if I return to a project after a few months, the relearning curve in VS isn’t nearly as steep as IB. This lets me stop worrying about minutia and enables me to focus on my UI design as a whole.

    A tightly integrated design/coding tool like Visual Studio isn’t Microsoft’s invention. That type of UI was first implemented at Borland with Delphi (and later with C++ and Java). Microsoft followed with Visual Basic, and later with C++/C# when .NET was launched. Also, NetBeans and some Eclipse UI builder plugins currently implement it. GUI design is hard enough. Apple’s IB/XCode implementation needs an overhaul.

  • Pingback:What to Think About When Starting iPhone/iPad Development « Measure Once, Cut Twice
    Posted at 09:36h, 30 March Reply

    […] in code. This allows me to layout complex screens with multiple widgets and images visually while still not relying on IB too much. The downside is it can lead to some inconsistency. For a trivial screen with one image […]

  • jade
    Posted at 02:09h, 20 April Reply

    I hate developers who do all the coding in XCode. Whenever I have to intervene in an iPhone project as a consultant to fix whatever bug it is, it takes me a considerable time and effort to look at their messy code just to understand the interface and the app flow. Whereas if they had used IB, it would’ve been a really simple task. For example, if I want to know what method is called when I click to that Search button, I just need to find what IBAction is connected to it instead of searching in all those .m.

    There are many reasons for you to use IB as much as you can, you may want to take a look at some of these articles:
    http://iphonedevelopment.blogspot.com/2009/10/dont-fear-interface-builder.html
    http://www.cerebrawl.com/2009/10/should-you-use-interface-builder/

  • xf
    Posted at 03:45h, 09 May Reply

    As a response to ‘jade’ comment: I hate all developers who do most of their work in IB.

    If IB would ease the task at hand, perfect, but in my own opinion, it just messes up everything. For simple applications it’s okay.. for complex applications it’s a no-no. It would have been an horror trying to set up most of the things in IB for a CA/GL app with many views and layers in a single controller. Of course you can, but I want the FULL power of creation and following steps.

    “…it takes me a considerable time and effort to look at their messy code just to understand the interface and the app flow…”: Good programmers structure their code, a messy code it’s not because not using IB, it’s because of lack of structured content. I’m used to check non-OO code, and it’s not painful at all. Actually it’s even easier sometimes. And sometimes I just get bored about the OO and MVC super-hyped trendies. Neither OO and ultra-MVC are good choices per se. But software engineers are the fewer in this new non-engineer software business it appears…

    Just my two cents.

  • charlie
    Posted at 10:49h, 17 May Reply

    im just staring out with a hello world app on my ipad. i have been a windows coder for 15 years and i have to tell you apple tool are CRAP !!!! you gotta be kidding ? VS make IB look like DO-DO

  • Palanichamy
    Posted at 09:13h, 21 May Reply

    I think IB reduces the code lines.It is a wonderful tool having lot of features.

  • Andy
    Posted at 06:05h, 01 June Reply

    I’ve just read the comment about IB, saying “It is a wonderful tool having lot of features.”… Don’t make me laugh!!!

    Why do Apple always overcomplicate things???

    No wonder I’ve tended to avoid Apple products over the years!

  • jose
    Posted at 04:29h, 07 June Reply

    @xf I’ve always created all of my apps using IB. Go ahead and hate me. IB is a powerful tool that can make code considerably easier to write and conceptually easier to understand. This is true even with the most complex of applications if you take the time to learn why. When I’ve needed to improve drawing performance, because of piling a bunch of transparent views on top of each other or the like, I just use nib2objc to generate code to incorporate into my project.

    And if you work in an enterprise environment where you’re not the only developer, or someone else is responsible for the user interface, heaven help you if you can’t sit down and quickly show UX designers what small changes will look like without recompiling 100,000 lines of code.

    To me it’s like saying that it’s stupid to use Core Data because you have the FULL power to work yourself directly with sqlite and optimize your app’s performance. Good luck with that.

  • ozzy
    Posted at 07:29h, 15 June Reply

    Honestly, after using C++ Builder or Delphi for about 2 minutes (or less), you will see that IB only convolutes things.

    Imagine:

    Drag a button onto your view.
    Double click the button, to open a code file where you can now type your code that occurs when the button is pressed. DONE! Automatically updates all relevant files.

    I’ve looked through 2 tutorial now, and still haven’t figured out how to get my IB view to be visible,
    although, by this point, I think if the button were there, you could click it and it might do something.

  • emarch
    Posted at 03:43h, 29 June Reply

    Yes, I have to agree IB is weird and funky and best. I see the advantages it offers, but Apple being king of nice clean visual controls communicating to the user and now developer what going has missed the mark. I used OWL, wxWidgets, MFC, .NET, and FLTK, and IB just isnt there as far as visually seeing how to do things easy. Why can’t they at least generate the methods and synthesize the properties when needed? Its time savings are deeply embedded in project portability and not in day to day hour by hour coding. Way too many weird mouse miles to do simple stuff. Wake Up Apple!!!

  • Davidmoreen
    Posted at 15:25h, 06 July Reply

    At the moment I have only been writing iphone applications for two months and I found that interface builder is limited, yet useful. I will use interface builder to make a wireframe of the application, and just modify the outlets respectively. I would like to go to a no-nib solution, however currently I am not experienced enough, and I don’t want to have to keep remembering xy placement (Interface builder has the dotted blue line which is very helpful for consistent alignment).

    I do find it really odd however that Interface Builder does not implement all of the attributes that are available in code. For example making a label bold…

  • Karl
    Posted at 09:49h, 07 July Reply

    I have been programming iPhone apps for over a year now but am also developing with Visual Studio in other project.

    Frankly said the Interface Builder is an absolute relic. The steps and clicks needed to code a single button implementation are more then 10! Compare that to Drag and Double-Click which is all that is needed with Visual Studio.

    I forgive Apple though because the iPhone is such a wonderful product but it must be said that the Interface Builder (as well as the Xcode debugger) is pathetic.

    • StackPointer
      Posted at 18:10h, 03 February Reply

      Have to agree. I’ve worked on VS most recently and the Borland tools prior to that. I’ve yet to see anything match Borland’s Delphi & C++ Builder – an absolute joy to work with. But VS was a close second. I find the visual aspect of IB to be pretty useless, and seem to be moving away from it for anything that is moderately complex. The debugger is lousy by comparison with VS and ultra lousy when compared with Borland.
      I have come to like the Apple components and there seems to be a way to accomplish just about anything you need to with them. But I could do that Borland’s VCL, also (occasionally having to write some Windows API code for system-level work. All these connections being setup manually seems ridiculous in this day.
      On a side note, I understand the evolution of ObjC; but they would have done well to transition toward a C++ variant which is a far better language IMO. As I said, I do like the components, but the ObjC implementation is absurdly verbose (some days I feel like I’m back to writing COBOL).
      It seems like it would be relatively easy to beef up the visual aspects and turn it into something, but AFAIK there isn’t a lot of interest in making these changes so I can live with it. I can always look back to the days of keypunches and recognize what an improvement XCode is.

  • SteveP
    Posted at 10:55h, 10 July Reply

    I’ve found IB useful for setting up the first static view of most of screens and setting all of the properties. As soon as you see blocks of code with more than a half dozen lines of UI component setup it is hint you might want to move it into IB. I don’t use it for much else though, just component wire up, layout, and properties. Doing anything behavioral, such as transitions and event wire-up seems to lead to VB-like spaghetti code.

  • aiak
    Posted at 23:03h, 13 July Reply

    “Setup your controllers and views in here.” is just what you should do with IB. I don’t think you would choose to adjust the values in CGRectMake in order to finally put it in the right location, rather than to drag it and place it directly on your simulator screen.

    it’s kind of hard for people including me to accept IB if they are too used to MS VS. but the more code one writes, the more convenient he’d find IB really is, especially for those “view-based applications”, as apple names them.

  • Anthony Hologram
    Posted at 05:55h, 23 July Reply

    As a developer who made 5 apps by hand coding, without a single XIB/NIB.. I knew I hated that thing from the start.

    However, our last app’s over budgetedness kind of turned my opinion. Here are the reasons you should leverage interface builder:

    – Design/implement GUI graphically, right brained like you will use the program
    – LESS LINES OF CODE to debug, write, remember to think about retain counts and spend dozens of lines setting up, say text field properties
    – Less memory management! The whole XIB is loaded/unloaded behind the scenes
    – Share the XIBs so DESIGNERS CAN LAY THEM OUT. No more time spent pixel pushing from a PSD comp, the designer will create the VERY LAYOUT U WILL USE! 😀
    – Less buggy code. IB makes sure you are initializing, configuring and disposing properly. (Not that *I* need that)
    – FASTER development of a complex UI. If you have 10+ styled elements on a view, it takes probably 50 lines of code to set them up right. With IB it takes zero.

    Now, the shortcomings.. (Rumored XCode 4 with integrated IB might fix some of this)
    – Terminology is confusing. Outlets, “File’s Owner” etc are never used in non-IB code, so pure coders don’t know what they do
    – Seems difficult to style/configure certain things. Attaching a UITableViewCell to a UITableView for example.
    – The magic of how the elements interact with the code is a hurdle for many at first.

    Ultimately I wouldn’t recommend newbies using IB. Get a firm grasp on the codez first and then you will see how IB can help you.

  • Juha
    Posted at 18:16h, 08 October Reply

    The problem with IB is that it has an extremely steep initial learning curve. You start it, and you have absolutely no idea what to do. However, once you understand IBOutlets, IBActions and how to connect to them in IB itself, it actually becomes extremely simple. You can create really complex user interfaces in a matter of minutes, writing only a minimal amount of code and, what’s more important, you can easily modify your user interface really easily and quickly with the mouse, rather than having to fine-tune numerical coordinates by hand and making test runs on every modification.

    Don’t get scared by the initial steep learning curve. Once you get over it, you will be making user interfaces in no time with minimal effort.

  • Brad
    Posted at 11:39h, 14 October Reply

    Thank you thank you thank you. Spent 3 hours trying to figure out how to do basic stuff in Interface Builder (getting nowhere) while also trying to learn a language, an IDE, and an API and it was driving me insane. Well on my way 15 minutes after reading this and ditching IB.

  • Tomas
    Posted at 11:46h, 31 October Reply

    Hi everyone 🙂
    I’m an IT university undergraduate student…
    I’m trying to learn something about Xcode and iPhone developing for graduation thesis, so I have to do all by myself 🙂
    On advice of my Prof, I’m trying to learn how create an iPhone app (just a MacOs app until now) without using IB, but I can’t find any guide or tutorial that don’t use it and that explain me that part of code needed to do what IB usually do.
    Could you help me with any guide or resources that you already know pls?
    Thank you very much 🙂

  • Mugunth
    Posted at 18:31h, 01 December Reply

    A equivalent web analogy would be, Why would anyone want to use CSS when you can do everything in HTML directly?

    • Rooz
      Posted at 07:12h, 01 June Reply

      No?

      Thats not related at all. IB is unnecessary but designed to make things easier, but the visual connections you make between your code and extra files and concepts added only make it difficult for begginers.

      You cant do anything without CSS anymore, save for bold some text or create bold text layouts. CSS is integral, directional, and simple.

  • FRANKIE
    Posted at 23:27h, 04 January Reply

    you make it sound so easy i’am using interface builder don’t know what iam doing.
    you use codes how where do i use those codes what programe do i need.
    is it possible create apps use windows base computers. iam new at this………

    THANK YOU……..

  • Pingback:When should new iOS developers start using Interface Builder? | Shine Technologies Blog
    Posted at 15:45h, 25 July Reply

    […] – and know exactly how it all worked.  A colleague of mine even wrote the blog  article “Why would you use Interface Builder for iPhone Development?”, that mirrored my exact feelings towards interface builder back […]

  • Pingback:When should new iOS developers start using Interface Builder? | The Shine Technologies Blog
    Posted at 00:32h, 29 July Reply

    […] – and know exactly how it all worked.  A colleague of mine even wrote the blog  article “Why would you use Interface Builder for iPhone Development?”, that mirrored my exact feelings towards interface builder back […]

  • Mehrad Sadegh
    Posted at 16:23h, 07 December Reply

    I agree with the writer, If you are not an expert in IB, you will find it very confusing. I have to admit that I am new to iOS/Mac development (joined a year ago, but worked as J2EE/Java developer for 5+ years), maybe I change my mind in the future, but for now I prefer to do most of the stuffs programmatically.

    I’m just wondering how many of you guys actually worked in a mid to big size project which required interface designing. I have never seen a mid-size+ project dependent to an interface designer, mainly because:

    1) Its hard to maintain and keep projects that use WYSIWYG designers under version control, You usually can not track small changes in the interface when using tools such as IB.

    2) You will be dependent to a tool that may change during the lifecycle of your project. Not all tools are backward compatible.

    3) Most of the time, you don’t use the components offered by your language of choice without sub-classing them and creating richer business components. I’m not sure how good this can be achieved via IB.

    Again, I do emphasize my lack of experience in Xcode, Objective-C and iPhone development. Maybe in the future I decide to use IB more often.

  • Andrew McDonald
    Posted at 03:59h, 28 January Reply

    I found this post through Google. I’m only interested in OpenGL apps, where all the content is drawn through GL, and so there’s no need for any kind of user interface design tool. It seems bizarre to me to use such a tool just for managing background controller objects. So, it’s great to see posts like this discussing how to just write code the old-fashioned way.

    But the code here is incomplete: as a newbie iOS developer (but experienced Windows C++ programmer) I need to know more about setting up the windows, views and controllers programmatically in applicationDidFinishLaunching: (or application:didFinishLaunchingWithOptions: which seems to be its modern replacement.)

    I’ve tried allocating a base UIViewController and assigning it to the UIWindow’s ‘rootViewController’ property, but the debug runtime still complains that “Applications are expected to have a root view controller at the end of application launch.”

    Any help would be appreciated – how do we create the simplest possible error-free iOS app, that does nothing more than painting the screen red, say?

    • Andrew McDonald
      Posted at 05:04h, 28 January Reply

      As usual, I discovered the problem in my test code shortly after posting. Not only must you assign to the UIWindow’s ‘rootViewController’ property, but your app delegate must also implement the optional ‘window’ property from the UIApplicationDelegate protocol. The UIWindow you allocate must be stored here in addition to being made key & visible.

      I don’t know why it’s tagged optional when it’s required to get the thing to work. Worse, if you don’t actually implement the property in your delegate but attempt to write to it anyway, you just get a runtime crash instead of a compiler error! That doesn’t sit well coming from a C++ background…

  • Mike C
    Posted at 05:20h, 17 November Reply

    I have been developing apps for about 5 years now. Yes, IB definitely had a steep learning curve, but once you get over it, it becomes incredibly handy in certain situations. As developers, we all know that there are 25 different ways to skin a cat, and knowing IB is just another tool. Some of my apps, I use no IB, some I use a little, some I use a lot. Depends on my needs. I think it’s a mistake not learn IB. That doesn’t mean you HAVE to use it for every visual object, just that sometimes it extensively simplifies certain coding drudgeries. It’s easier to click a few checkboxes than to write a line of code for each one of the properties available for any particular object. If I need a quick UILabel, drag, click click click click. Presto. If I need more control, I just build it myself. Whatever the situation calls for.

    Thanks for listening to my monolog.

    The end.

    Mike

Leave a Reply

%d bloggers like this: