TweetFollow Us on Twitter

Interactive Development With ActiveDeveloper

Volume Number: 20 (2004)
Issue Number: 4
Column Tag: Programming

Interactive Development

by Aidan A. Reel

Interactive Development With ActiveDeveloper

An Introduction to Interactive Development and a review of Inter*ACTIVE - Technology's ActiveDeveloper

Introduction

This article introduces interactive development, an approach that increases your quality and productivity as a developer. It also reviews a toolset that permits this style of development to be used with Apple's development tools. Before delving into the grit of the article, a short computing backdrop explains where my interest in interactive development stems from. We will see that interactive development is not new, but has been supported by some IDEs for over 30 years. I'll outline the functionality that tools need to provide in order to be regarded as interactive development tools. I will discuss features within Objective-C that can be utilized in order to provide such tools. Finally, I will introduce, and review ActiveDeveloper (AD), a toolset that brings interactive development to ProjectBuilder and Xcode.

Backdrop

As a developer in the early 1990s, I coded with NeXTSTEP. NeXTSTEP allowed me to truly grasp Object Orientation. It was using instances in InterfaceBuilder that turned on the light. That phrase, 'using instances', is central to this article. I became aware that Brad Cox based his Objective-C's extensions on a language called Smalltalk. This introduced me to the language that I would use continually for the next 10 years, namely Smalltalk.

Smalltalk and its various IDEs (ParcPlace, IBM, Digititalk) taught me the power of having no compile-link-run cycle and having access to the instances within a running application. When I understood how to use tools such as workspaces, object inspectors and the stack based debugger properly, I realized were NeXT had got its power from. Again it was working with instances. Smalltalk allows you to investigate a running program in real time. It is possible to halt execution, edit code, change attribute values on-the-fly, and resume execution. In other words, you, as a programmer can operate on your living program. You can inspect instances, traverse references, observe the actual state of your program, i.e. objects, at any point, as it runs. Having seen how the program is working (or not), it is possible to edit methods there and then in the debugger, and re-execute it. All of these activities flow from the keyboard. When you save a method, it is not only saved but compiled, and available for execution. Your workflow is not interrupted waiting for the compile and linking to complete, restarting the application and directing it back to the point of execution under investigation. You start where you left off, all in the time it takes to press command-s. These tools are an intrinsic part of Smalltalk IDEs.

So, after many years firmly settled in the Smalltalk industry, I had an opportunity to do some development for Mac OS X. I found myself staring at ProjectBuilder, and InterfaceBuilder. After the initial shock of how familiar they still were, and the fact that I was able to use my 1993 copy of NeXTSTEP Programming by Garfinkel and Mahoney to reintroduce myself to the developer tools and frameworks, when all was said and done I was back to the compile-link-run cycle. Regardless of the richness and maturity of Cocoa, returning to the disruption of start stop start stop programming was extremely frustrating. I soon found myself browsing the web for tools that sounded as if they supported some form of interactive development. Eventually, I found a reference to ActiveDeveloper and sat down to see what it offered.

That brings us (more or less) up to date. I am a developer whose main development experience has been supported by a language, and toolset that permitted a very interactive style of development. Faced with an environment that did not natively support such an approach, I started to use a 3rd party product that pertained did. Now you have an opportunity to read about this style, and experiment with the same.

What Interactive Development Is and What it is Not

Lets start with the negative, what interactive development isn't. This is not another methodology aimed at removing identified problems in software development. Nor is it a process encouraging the adoption of a unified set of tasks that reduce the risk inherent in software development. Interactive development is a lot more humble. To the developer, it is about a new set of (easy to use) tools, rather than a new (difficult to appreciate) development strategy.

It is closer to the spirit of extreme programming in that it will enthuse the developer, and inspire them by making it easier to write robust code. As they realize that their code is improving at the same time as their productivity is increasing, their morale and confidence improves.

Before a developer can fluently use these new tools, they need to understand the mindset to be adopted. You will be pleasantly surprised to find that this mindset is very easy to adopt, and soon becomes second nature.

There are two aspects to interactive development. One is interactive investigation, and the other is interactive coding.

Interactive investigation is the task of understanding classes and frameworks by investigating instances of the classes involved. You create instances of any class, and inspect them while they are active. It is possible to send messages to their attributes and to inspect the resulting object. A tool, normally referred to as a workspace, provides a general context in which code can be written and executed. So, for example, the following code,

[[NSWorkspace sharedWorkspace] launchedApplications];

could be written in a workspace and executed. The resulting object can be inspected in an object inspector, or browser. Inspectors provide the developer with a graphical interface to display, and browse an instance's values and references. You can traverse the various references to display other instances. Inspectors also provide a coding area whose context is the currently selected attribute. Using this context permits the sending of messages to the selected attribute. This kind of exploration and investigation cements the developer's understanding of the classes under scrutiny.

This kind of investigation normally melts into incremental development. A developer will start by reading some documentation or guessing that a particular class may suit their needs. Taking these classes, and creating instances and investigating their behavior, the developer can confirm that these classes do indeed support their requirements. Typically, if they have written code that confirms this, then this very same code will probably be quite close to what they require. So, the next step is to move this code to a method. Note that I say move rather than convert. Because you are performing your investigation in true Objective-C, this task is typically a matter of copy & paste, changing some temporary variables into instance attributes, which is not a major task. There is no converting, rewriting, or debugging of a new piece of code.

Developers can also be faced with having to quickly understand complex classes in order to enhance or debug. With interactive investigation, the developer can work within a workspace (away from the complexity of the existing application) on salient classes, inspecting instances, traversing references, and sending messages to attributes. In effect, building up a mental picture of the instance graph. In the same way that a picture is worth a thousand words, being able to interrogate live instances is worth a thousand pages of documentation. A slight exaggeration but I think you will understand the sentiment.

Next, interactive coding avoids the compile-link-rerun cycle. In doing so, the programmer is freed to continually concentrate on the problem at hand. Being able to sustain an uninterrupted train of thought increases developer productivity, and quality of work. Imagine a writer being expected to save after every edit, issuing reformat commands, linking in adjoining paragraphs, and restarting viewers before they could see the effect of their changes. As a writer, the disruption to the creative process would be unacceptable. Yet, that is the process accepted, and expected by most programmers. Interactive coding avoids the disruption, releasing you to work at your own natural pace. It needs the support of special tools, editors that avoid having to recompile the classes just edited, re-linking modules and rerunning the application. The editors should allow you to reload changes even while the application is running and allow the developer to observe the changes, in action, immediately.

How it works

Interactive Investigation

The good news with interactive investigation is that the underlying mechanisms used by these tools (workspaces and object inspectors) do not necessarily have to be understood by developers in order to avail themselves of their functionality.

With regard to ActiveDeveloper, your project includes a library supplied with the product suite. The process to follow in order to include this library is explained in detail in the supplied documentation. It is important to note that the inclusion of this library is only required during development; the deployed application has no dependencies on ActiveDeveloper, and as such, there is no decoupling project required after code freeze. You can confidently ship the packaged application.

Interactive Coding

Interactive coding, as supported by ActiveDeveloper, is achieved via dynamically loading categories. Since categories play a major role in ActiveDeveloper's support for interactive coding, I have included this section as a refresher on categories. If you are experienced in the use of categories and dynamic loading, feel free to skip the next two sections.

Categories

Categories are an extension to Objective-C. The extension is used:

  • as a structural aid, permitting a developer to arrange their code into distinct sets of methods.

  • to extend existing classes. Developers can add methods to existing classes when they have no access to source code.

Rather than having your class contained in one large monolithic file, it is possible (using categories) to split the class into a number of smaller files. We organize the files to hold methods that have some kind of similarity, or relationship to each other. So, for example, we could group all accessor methods together in one file, all private methods in another file, methods that implement persistency in a third file, and so on. The intention is that this separation leads to the class being easier to comprehend and maintain.

It is possible to add categories to classes that you do not have the source code for. It is by using categories that companies such as OmniGroup can extend Apple's Cocoa Framework. It is important to appreciate that since we do not need access to the source code of the class in order to extend it, we do not need to recompile the entire class in order to include the new category methods. We just compile the methods in the category. This fact has some very powerful side effects, as we will see later.

Each category can reside in its own file set (interface and implementation). The following listings display templates of category interface & implementation files.

Listing 1: Category Interface Template

Category Interface Template
#import   "CLASSNAME.h"
@interface   CLASSNAME   (   CATEGORYNAME   )
METHOD DECLARATIONS
@end

Listing 2: Category Implementation Template

Category Implementation Template
#import   "CATEGORYNAME.h"
@implementation   CLASSNAME   (   CATEGORYNAME   )
METHOD DEFINITIONS
@end

The interface file imports the class's main interface file and proceeds to declare itself as a category by virtue of the (CATEGORYNAME) after the CLASSNAME. We then provide a list of the methods that this category will contain. The implementation file imports the category interface, declares the category name in the same manner as the interface, and proceeds to provide the method definitions.

There are some restrictions in using categories. and the main one is that you cannot add new attributes to a class. In the above interface template, we only declare methods, not attributes.

Related to this is the fact that category declarations do not actually need to provide an interface file at all. We could simply provide the implementation file.

Note that if a method with the same name resides in more than one category, it is unpredictable as to which method will get executed if called. Thus the developer of an extension should try an ensure that name clashes are unlikely. One convention is to use prefixes to any method names defined in categories that extend classes you do not own.

Dynamic Loading

The Objective-C runtime supports the loading of category files at runtime, referred to as dynamic loading. This is a very powerful feature enabling classes to be extended during an application's lifetime. All instances belonging to the category's class now have access to those newly loaded methods, even instances created before the category was loaded.

There is no reason why a category cannot be loaded numerous times during an application's lifetime.

It is these facts that allow tools to support interactive development. The special editors mentioned earlier ensure that after the edits have been saved, the category file is reloaded into the running application.

There is an important caveat to dynamic loading and its use in supporting inactive coding editors. I will return to this when you have gained more of an understanding of ActiveDeveloper.

Summary

In this first part of the article, we described techniques that offer a more productive, interactive, exploratory style of development, and gave them the umbrella term of interactive development. We explained that these techniques can only be adopted if supported by appropriate tools, such as workspaces (supports the execution of isolated snippets of code), object inspectors (permits the browsing of instances), and advanced editors (provides the editing and loading of category files thus avoiding the compile-link cycle).

We now turn our attention to one such tool set, available to use in conjunction with Apple's Developer Tools.

The Product

ActiveDeveloper is a product marketed by Inter*ACTIVE - Technology (www.interactive-technology.com), that facilitates interactive development. It runs on multiple platforms (Mac OS X, Windows WOF).

A demo version is available and I suggest, if you already haven't done so, you obtain a copy, and use it as you read along.

You will notice from the web site styling, and AD's interface, that the product has its genesis firmly in NeXTSTEP. The styling may not be to everyone's taste, but I found it reassuring to know that the product has such a long lineage.

The demo version has the normal limitation found in demos of not being able to save your work (your workspace code and editor code). It has another, more annoying limitation, a time out, apparently based on the number of explorations made during a session. I found the time out to be too frequent, and pretty frustrating. I believe the creators are aware of this, and are considering increasing the limit.

As of version 2.15, AD includes a comprehensive user guide that takes you through installation, the most frequently used tools in the package, and explaining the rules of how to structure your own existing projects in order to use the AD tools.

When AD starts, you are presented with AD's main window, the console. You will tend to use this window to observe system messages, and to start your applications. One precompiled sample application is available immediately to start investigation, the ActiveAppKitExplorer.


Figure 1. The ActiveDeveloper Console.

On clicking start with ActiveAppKitExplorer selected, the following window appears.


Figure 2. The ActiveAppKitExplorer main window.

You have just started a new AppKitExplorer application that consists of this single window, and have entered into an ActiveDeveloper session with it. I initially found the Info Panel in the window title confusing. I mistook it for the info panel of ActiveDeveloper rather than the single window of a new, separate application.

The AppKitExplorer serves as a to explore all of the Cocoa classes available to ActiveDeveloper out of the box. As you use AD, you will find that you also avail yourself of this application as a quick way to get an AD session up and running.

Interactive Investigation

Typing shift-command-w from AD opens our first workspace.


Figure 3. ActiveDeveloper Workspace.

The top pane (the import pane) allows you to add import statements, by default both <Foundation/Foundation.h> and <AppKit/AppKit.h> are imported. These imports provide the context for the lower pane (the coding pane) used to construct code. Only classes declared in interface files imported via the import pane are available for use in the coding pane. Since Foundation.h and Appkit.h are imported by default, any class from these frameworks can be investigated. The 3 buttons above the import pane are all used to execute the currently selected code in the coding pane. All execute the code, but present the results in different ways. The Eval button simply executes the code, there will be no feedback (other than that in the code) to indicate that the code has been executed. The Display button will display the textual representation of the object returned by the last statement in the highlighted code. This textual representation will appear in the Transcript tab of AD's console. Finally, the Inspect button will present the object returned by the last statement in an inspector, referred to in AD as a runtime object browser.

Remember we said that workspaces allow us to write small code samples and execute them. Returning to the example from earlier, type the following into the coding pane.

[[NSWorkspace sharedWorkspace] launchedApplications];

Note that this code has nothing to do with the application currently running. Because we have access to the Objective-C runtime via the running application, there is nothing to prevent us from creating instances from any class, as long as the class is in the context of the workspace. So the entire Cocoa API is available for such exploration. In this case, from within the workspace we have obtained an instance that refers to all the applications currently running. We can close them, hide them, etc., all from AD's workspace. This is the kind of flexibility and powerful exploration that working with instances exposes.

A word of warning from the Smalltalk community. "Do not perform brain surgery on yourself." It would be a simple matter to kill AD, or any other application, from within this workspace. I leave that as an exercise for the student! Make sure you have saved any important work beforehand.

Highlight this code and click on the Inspect button.


Figure 4. Executing Objective-C code in a Workspace.

A runtime object browser similar to the following will appear.


Figure 5. Exploring an instance in the Runtime Object Browser.

This window displays instances in the top left hand side browser panel, the root panel. The resulting object from the executed statement is an instance of NSCFArray, so we see such an instance displayed in our runtime object browser. The properties of the instance are visible in the adjoining column (in this case elements of the array) and by choosing these properties and traversing rightwards we can explore any instance on display. The lower pane is used to display the textual representation of the currently selected instance. This pane can also be used as a coding pane hence the appearance of the Eval Display Insect trio. The context of the pane depends on the selected instance. For example, select one NSCFArray in the browser panel, type the following code snippet after the textual representation in the coding pane:

[self className]; 

Now, highlight and copy this statement, then click Display. We will see NSCFArray appear in the Transcript tab. Select any item in the array, paste our copied statement after the textual representation, select, and execute our statement via Display, and we now see NSCFDictionary appear. If we repeat this by choosing an item in the Dictionary, we should see NSCFString appear in the Transcript.

What all this goes to prove is that the coding pane's context is the context of the selected attribute. To reinforce this point, click on NSApp in the runtime object browser, and select the _keyWindow attribute. In the coding pane, type in the following code:

[self setTitle:@"AppKitExplorer Main Window"];

Highlight and Eval. You should see the title of our running application change.

So, if we want to do some random exploration, we can use a workspace to create instances for us. There are more examples of this type of ad hoc exploration in the accompanying user guide.

More usually, we use the workspace to initiate exploration of the application we have just started. Going back the workspace, type:

[NSApp delegate];

Now, inspect it. The runtime object browser will display the controller in its list of objects. Again, we can traverse this object, write code in the coding pane, and continue on our Eval, Display, Inspect circuit.

It is quite easy not to realize how impressive the above examples are. In the matter of the few moments it takes to start AD, and its demo, AppKitExplorer, we can start to create instances of any class in Cocoa and examine it. Think for a moment of what is involved in setting up a project in order to explore a Cocoa class: setting up a new application, creating classes and methods in order to create instances, and coding a GUI to display the results. Not to mention relying on NSLog statements, or setting breakpoints to use GDB to provide limited access to attributes.

Comments On ActiveDeveloper's Support for Interactive Investigation

Overall, ActiveDeveloper supports the standard functions required to carry out instance based investigations. The product gives the impression that it is built by developers who focus on the technical aspects rather than on usage. This is no bad thing, but does have the downside that the product does not do itself justice in terms of it's interface, and to a lesser extent, its usability.

There are numerous user aids that could be included to enhance the developer's life. As the coding panes stand at the moment, they provide basic coding support (matching brackets). Developers have grown used to more support in terms of syntax coding, emacs like text selection, code completion, etc.. The coding panes could be improved to allow the selection of discreet areas of text, and have it Evaled, Displayed, or Inspected from the keyboard rather than having to break off to use a pointing device. Including the commands in the popup menu would help.

When traversing the attributes in the runtime object browser, the coding panes lose their contents. It would be nice if there was some technique to retain code that was written earlier. Related to this, it would be good to have more preferences to play with. Apart from developers loving their fonts, and color schemes, they also have their own preferences as to window layout, multiple or single browsers, etc.. The preferences available could be increased.

Given the technical achievement underlying these tools, I feel a little whiny in these usability comments. Although they are important in their own right, we should not over look the fact that interactive investigation functionality is there, now, in a stable, and robust form. The usability issues do not prevent you from increasing your productivity, but you would have an even smoother investigation process if they existed.

Interactive Coding.

AD takes advantage of being able to dynamically load a category at runtime to side step the compile-link cycle. In keeping with the rules of categories, and dynamic loading when using AD's class editor, we can load new classes, load new methods onto existing classes, and reload existing methods. Dynamic loading does not support the reloading of existing class definitions, or code that contains global symbols that are already present in the running application.

So, avoiding the compile-link cycle is achieved by placing those methods that you will be working on most in a category file, and using a special editor to do your coding.

Typing shift-command-c from the console brings up the editor window.


Figure 6. ActiveDeveloper's Class Editor.

We see the familiar Eval, Display, and Inspect buttons. This means you can perform interactive investigation from within the editor as you are coding. This turns out to be quite a convenient feature. There also appears a new Load button. This is used to dynamically load a category into the application that is currently running under AD's tutelage.

The top left hand pane is used to provide import statements at the start of a header file (referred to as the prefix import pane) while the bottom left hand pane is used to provide import statements that you wish to appear at the end of header files (referred to as the postfix import pane). The middle left hand pane displays the signature of methods contained in the file, and can be used to navigate to methods by clicking on the signature. Finally, the right hand pane is the coding pane.

When a class is constructed to have its interface details contained in the implementation file, AD will reward you by keeping the interface file in sync with the implementation file. This feature releases you from having to maintain both the interface and implementation files. The auto generation of the header occurs when saving the implementation file. Since saving is disabled in demo mode you will not be able to observe this feature in action.

As already stated, the documentation that comes with AD has improved substantially over the last few releases. It now contains a number of examples showing how to activate your existing projects.

Comments On ActiveDeveloper's Support for Interactive Coding

The process of activating your own projects is covered comprehensively in AD's user guide. Once you activate two or three projects you will find that it is a pretty straightforward, almost mechanical, process.

AD's interactive coding editor utilizes the same coding pane as the object browser and workspace, providing a consistent feel between the tools. You will find working between them to be transparent.

Returning to the caveat mentioned earlier, one fact to be aware of when using categories is there is currently no way to delete a method from a running application once it has been loaded. This derives from the fact that there is no mechanism available in Objective-C to unload categories. The original purpose was to load methods into an application, and keep them there. What this means for us is that although we may have deleted a method from the category file, its last definition will still exist in the application's method space until its quits. In reality this is not a serious problem as the method will not exist the next time the application is executed. It is also possible to provide an empty method as your last edit, such as

methodName;   {   }

Another restriction related to the nature of categories is the fact that you cannot use AD to add or remove instance variables, or change the super class. This needs to be done within Apple's development environment. I found that this does not happen too often. Most time is spent modifying behavior rather than properties.

The same comments regarding the GUI of the class editor are applicable here. Given the quality of editors on the market, AD's coding panes are somewhat lacking. In the editor's case, this is quite unfortunate in that you will be spending most of your time in AD's editors, rather than in Apple's IDE, because of the dynamic loading support. So, you will miss functions, such as auto formatting, syntax coloring, font selection, color schemes, all the usual suspects.

GDB and AD - Interactive Debugging

An area that I haven't mentioned yet is interactive debugging. It is possible to use GDB and AD in concert. You can attach GDB to a running application started from AD, using the application's process id. From within GDB, you can set breakpoints, etc., as normal, and have the application pause. You can use AD to edit a method, and reload it. When you use continue execution in GDB, you will find that the new edition of the method is available for execution.

It is also possible to inspect objects using the memory address displayed in GDB's value column.

Inspect an instance via its memory address

This code snippet can be written, and Inspected in any of AD's 
coding panes. Replace Ox123456 with the address of the instance you are interested in.

id anObject = (id) 0x123456;
return anObject;


Figure 7. GDB and AD in Concert. Note the address in GDB, the code snippet in the Workspace and the instance displayed in the object browser.

This leads to a very flexible debugging environment where you can work, as it were, in three dimensions. The first being the time line of the stack trace, the second being on-the-fly code changes, and having the debugger execute it when the application is continued, and finally, the 3rd line of attack being the ability to completely traverse live instances in object browsers.

Closing Comments

I have taken you, at quite a pace, through the essence of interactive development, and the tool functionality needed to support it. Within the Objective-C arena, I explained the language features that permit such tools to exist, and introduced you to one such toolset. Finally, I now present my ranking as to how well I feel AD compares to the interactive development tool set provided by Smalltalk IDEs.

Some interactive development tools are missing, such as a true Smalltalk style debugger, but there are fundamental differences between the Objective-C runtime, and Smalltalk runtimes which mean that certain Smalltalk tools, such as the debugger, can not be replicated completely. So this is not a criticism of AD more than a reality check. So, for features supported I would award 9 out of 10.

From my usage of the tools over the last few months, I have found it stable and reliable, and I use it constantly. Out of 10, I would give ActiveDeveloper's tools a rating of 8 just for the sheer power that the functions it supports provide. A 10 would be easy to award once the GUI supports more of the functions that developers have come to expect.

The documentation does not cover all the functionality provided by AD. There is little discussion on what the other tabs in the console are for, nor how to use the buttons, such as retain and release, in the object browser. Little mention is given to the ability to start Interface Builder from AD, and use AD to investigate the inner instances of IB as it is running. You find it mentioned in the FAQ page. But the documentation does achieve the most important goal, that of explaining how to set up your environment, and how to use the most important features. It takes you, in a logical sequence, through the most important functions, and by the end you will be up and running with your own projects activated. Marks here are 7 out of 10.

As an aside, retain and release allow you to quickly add/remove an instance to the root panel of the object browser. If you know you will need to revisit a selected instance buried deep in an object graph, by pressing retain, the selected instance will appear in the root panel. It is now at hand for future use. When it is no longer of interest, select it, press release, and it disappears. A very useful feature.

Product support has been excellent, all queries were answered promptly, and I feel there was genuine commitment to the product. Nine out of 10 for product support.

So an overall score of 8, which is well deserved.

In closing, I hope you enjoyed reading this article and found it easy to understand. More over, I hope that you have been introduced to something that will have a lasting beneficial effect on your development style.


Aidan has finally returned home. Having wandered away from NeXTSTEP around 1995, he quietly slipped back through Cocoa's doors last year. In the meantime he worked on some of Europe's leading Smalltalk projects, gaining an appreciation for simplicity. He can be contacted at aidanreel@mac.com.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Top Mobile Game Discounts
Every day, we pick out a curated list of the best mobile discounts on the App Store and post them here. This list won't be comprehensive, but it every game on it is recommended. Feel free to check out the coverage we did on them in the links... | Read more »
Price of Glory unleashes its 1.4 Alpha u...
As much as we all probably dislike Maths as a subject, we do have to hand it to geometry for giving us the good old Hexgrid, home of some of the best strategy games. One such example, Price of Glory, has dropped its 1.4 Alpha update, stocked full... | Read more »
The SLC 2025 kicks off this month to cro...
Ever since the Solo Leveling: Arise Championship 2025 was announced, I have been looking forward to it. The promotional clip they released a month or two back showed crowds going absolutely nuts for the previous competitions, so imagine the... | Read more »
Dive into some early Magicpunk fun as Cr...
Excellent news for fans of steampunk and magic; the Precursor Test for Magicpunk MMORPG Crystal of Atlan opens today. This rather fancy way of saying beta test will remain open until March 5th and is available for PC - boo - and Android devices -... | Read more »
Prepare to get your mind melted as Evang...
If you are a fan of sci-fi shooters and incredibly weird, mind-bending anime series, then you are in for a treat, as Goddess of Victory: Nikke is gearing up for its second collaboration with Evangelion. We were also treated to an upcoming... | Read more »
Square Enix gives with one hand and slap...
We have something of a mixed bag coming over from Square Enix HQ today. Two of their mobile games are revelling in life with new events keeping them alive, whilst another has been thrown onto the ever-growing discard pile Square is building. I... | Read more »
Let the world burn as you have some fest...
It is time to leave the world burning once again as you take a much-needed break from that whole “hero” lark and enjoy some celebrations in Genshin Impact. Version 5.4, Moonlight Amidst Dreams, will see you in Inazuma to attend the Mikawa Flower... | Read more »
Full Moon Over the Abyssal Sea lands on...
Aether Gazer has announced its latest major update, and it is one of the loveliest event names I have ever heard. Full Moon Over the Abyssal Sea is an amazing name, and it comes loaded with two side stories, a new S-grade Modifier, and some fancy... | Read more »
Open your own eatery for all the forest...
Very important question; when you read the title Zoo Restaurant, do you also immediately think of running a restaurant in which you cook Zoo animals as the course? I will just assume yes. Anyway, come June 23rd we will all be able to start up our... | Read more »
Crystal of Atlan opens registration for...
Nuverse was prominently featured in the last month for all the wrong reasons with the USA TikTok debacle, but now it is putting all that behind it and preparing for the Crystal of Atlan beta test. Taking place between February 18th and March 5th,... | Read more »

Price Scanner via MacPrices.net

AT&T is offering a 65% discount on the ne...
AT&T is offering the new iPhone 16e for up to 65% off their monthly finance fee with 36-months of service. No trade-in is required. Discount is applied via monthly bill credits over the 36 month... Read more
Use this code to get a free iPhone 13 at Visi...
For a limited time, use code SWEETDEAL to get a free 128GB iPhone 13 Visible, Verizon’s low-cost wireless cell service, Visible. Deal is valid when you purchase the Visible+ annual plan. Free... Read more
M4 Mac minis on sale for $50-$80 off MSRP at...
B&H Photo has M4 Mac minis in stock and on sale right now for $50 to $80 off Apple’s MSRP, each including free 1-2 day shipping to most US addresses: – M4 Mac mini (16GB/256GB): $549, $50 off... Read more
Buy an iPhone 16 at Boost Mobile and get one...
Boost Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering one year of free Unlimited service with the purchase of any iPhone 16. Purchase the iPhone at standard MSRP, and then choose... Read more
Get an iPhone 15 for only $299 at Boost Mobil...
Boost Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering the 128GB iPhone 15 for $299.99 including service with their Unlimited Premium plan (50GB of premium data, $60/month), or $20... Read more
Unreal Mobile is offering $100 off any new iP...
Unreal Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering a $100 discount on any new iPhone with service. This includes new iPhone 16 models as well as iPhone 15, 14, 13, and SE... Read more
Apple drops prices on clearance iPhone 14 mod...
With today’s introduction of the new iPhone 16e, Apple has discontinued the iPhone 14, 14 Pro, and SE. In response, Apple has dropped prices on unlocked, Certified Refurbished, iPhone 14 models to a... Read more
B&H has 16-inch M4 Max MacBook Pros on sa...
B&H Photo is offering a $360-$410 discount on new 16-inch MacBook Pros with M4 Max CPUs right now. B&H offers free 1-2 day shipping to most US addresses: – 16″ M4 Max MacBook Pro (36GB/1TB/... Read more
Amazon is offering a $100 discount on the M4...
Amazon has the M4 Pro Mac mini discounted $100 off MSRP right now. Shipping is free. Their price is the lowest currently available for this popular mini: – Mac mini M4 Pro (24GB/512GB): $1299, $100... Read more
B&H continues to offer $150-$220 discount...
B&H Photo has 14-inch M4 MacBook Pros on sale for $150-$220 off MSRP. B&H offers free 1-2 day shipping to most US addresses: – 14″ M4 MacBook Pro (16GB/512GB): $1449, $150 off MSRP – 14″ M4... Read more

Jobs Board

All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.