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

Netflix Games expands its catalogue with...
It is a good time to be a Netflix subscriber this month. I presume there's a good show or two, but we are, of course, talking about their gaming service that seems to be picking up steam lately. May is adding five new titles, and there are some... | Read more »
Seven Knights Idle Adventure drafts in a...
Seven Knights Idle Adventure is opening up more stages, passing the 15k mark, and players may find themselves in need of more help to clear these higher stages. Well, the cavalry has arrived with the introduction of the Legendary Hero Iris, as... | Read more »
AFK Arena celebrates five years of 100 m...
Lilith Games is quite the behemoth when it comes to mobile games, with Rise of Kingdom and Dislyte firmly planting them as a bit name. Also up there is AFK Arena, which is celebrating a double whammy of its 5th anniversary, as well as blazing past... | Read more »
Fallout Shelter pulls in ten times its u...
When the Fallout TV series was announced I, like I assume many others, assumed it was going to be an utter pile of garbage. Well, as we now know that couldn't be further from the truth. It was a smash hit, and this success has of course given the... | Read more »
Recruit two powerful-sounding students t...
I am a fan of anime, and I hear about a lot that comes through, but one that escaped my attention until now is A Certain Scientific Railgun T, and that name is very enticing. If it's new to you too, then players of Blue Archive can get a hands-on... | Read more »
Top Hat Studios unveils a new gameplay t...
There are a lot of big games coming that you might be excited about, but one of those I am most interested in is Athenian Rhapsody because it looks delightfully silly. The developers behind this project, the rather fancy-sounding Top Hat Studios,... | Read more »
Bound through time on the hunt for sneak...
Have you ever sat down and wondered what would happen if Dr Who and Sherlock Holmes went on an adventure? Well, besides probably being the best mash-up of English fiction, you'd get the Hidden Through Time series, and now Rogueside has announced... | Read more »
The secrets of Penacony might soon come...
Version 2.2 of Honkai: Star Rail is on the horizon and brings the culmination of the Penacony adventure after quite the escalation in the latest story quests. To help you through this new expansion is the introduction of two powerful new... | Read more »
The Legend of Heroes: Trails of Cold Ste...
I adore game series that have connecting lore and stories, which of course means the Legend of Heroes is very dear to me, Trails lore has been building for two decades. Excitedly, the next stage is upon us as Userjoy has announced the upcoming... | Read more »
Go from lowly lizard to wicked Wyvern in...
Do you like questing, and do you like dragons? If not then boy is this not the announcement for you, as Loongcheer Game has unveiled Quest Dragon: Idle Mobile Game. Yes, it is amazing Square Enix hasn’t sued them for copyright infringement, but... | Read more »

Price Scanner via MacPrices.net

Apple introduces the new M4-powered 11-inch a...
Today, Apple revealed the new 2024 M4 iPad Pro series, boasting a surprisingly thin and light design that pushes the boundaries of portability and performance. Offered in silver and space black... Read more
Apple introduces the new 2024 11-inch and 13-...
Apple has unveiled the revamped 11-inch and brand-new 13-inch iPad Air models, upgraded with the M2 chip. Marking the first time it’s offered in two sizes, the 11-inch iPad Air retains its super-... Read more
Apple discontinues 9th-gen iPad, drops prices...
With today’s introduction of the new 2024 iPad Airs and iPad Pros, Apple has (finally) discontinued the older 9th-generation iPad with a home button. In response, they also dropped prices on 10th-... Read more
Apple AirPods on sale for record-low prices t...
Best Buy has Apple AirPods on sale for record-low prices today starting at only $79. Buy online and choose free shipping or free local store pickup (if available). Sale price for online orders only,... Read more
13-inch M3 MacBook Airs on sale for $100 off...
Best Buy has Apple 13″ MacBook Airs with M3 CPUs in stock and on sale today for $100 off MSRP. Prices start at $999. Their prices, along with Amazon’s, are the lowest currently available for new 13″... Read more
Amazon is offering a $100 discount on every 1...
Amazon has every configuration and color of Apple’s 13″ M3 MacBook Air on sale for $100 off MSRP, now starting at $999 shipped. Shipping is free: – 13″ MacBook Air (8GB RAM/256GB SSD): $999 $100 off... Read more
Sunday Sale: Take $150 off every 15-inch M3 M...
Amazon is now offering a $150 discount on every configuration and color of Apple’s M3-powered 15″ MacBook Airs. Prices start at $1149 for models with 8GB of RAM and 256GB of storage: – 15″ M3 MacBook... Read more
Apple’s 24-inch M3 iMacs are on sale for $150...
Amazon is offering a $150 discount on Apple’s new M3-powered 24″ iMacs. Prices start at $1149 for models with 8GB of RAM and 256GB of storage: – 24″ M3 iMac/8-core GPU/8GB/256GB: $1149.99, $150 off... Read more
Verizon has Apple AirPods on sale this weeken...
Verizon has Apple AirPods on sale for up to 31% off MSRP on their online store this weekend. Their prices are the lowest price available for AirPods from any Apple retailer. Verizon service is not... Read more
Apple has 15-inch M2 MacBook Airs available s...
Apple has clearance, Certified Refurbished, 15″ M2 MacBook Airs available starting at $1019 and ranging up to $300 off original MSRP. These are the cheapest 15″ MacBook Airs for sale today at Apple.... Read more

Jobs Board

IN6728 Optometrist- *Apple* Valley, CA- Tar...
Date: May 8, 2024 Brand: Target Optical Location: Apple Valley, CA, US, 92308 **Requisition ID:** 824398 At Target Optical, we help people see and look great - and Read more
Nurse Anesthetist - *Apple* Hill Surgery Ce...
Nurse Anesthetist - Apple Hill Surgery Center Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Now Read more
LPN-Physician Office Nurse - Orthopedics- *Ap...
LPN-Physician Office Nurse - Orthopedics- Apple Hill Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Read more
Supervisor/Therapist Rehabilitation Medicine...
Supervisor/Therapist Rehabilitation Medicine - Apple Hill (Outpatient Clinic) - Day Location: York Hospital, York, PA Schedule: Full Time Sign-On Bonus Eligible Read more
BBW Sales Support- *Apple* Blossom Mall - Ba...
BBW Sales Support- APPLE BLOSSOM MALL Brand: Bath & Body Works Location: Winchester, VA, US Location Type: On-site Job ID: 04388 Job Area: Store: Sales and Support Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.