Documentation

API Overview

Classes, Protocols and Categories by Groups

Network and Communication

ETListenSocket

Description forthcoming.

NSFileHandle (SocketAdditions)

Category on NSFileHandle which adds support for creating protocol-agnostic sockets.

ETSocket

The ETSocket class provides a simple wrapper around a socket. The socket is opened when the object is created, and closed when it is destroyed.

NSObject (ETListenSocketDelegate)

Informal protocol for delegates to listening sockets.

NSObject (ETSocketDelegate)

Informal protocol for socket delegates.

<ETSocketFilter>

Protocol for socket data filters. Data sent or received by an ETSocket instance will be pushed through a chain of filters conforming to this protocol.


Reflection

ETProtocolMirror

Mirror-based reflection API for Etoile

Description forthcoming.

ETObjectMirror

Mirror-based reflection API for Etoile

Description forthcoming.

ETMethodDescriptionMirror

Mirror-based reflection API for Etoile

Used to mirror a method when we only know its name

NSObject (Etoile)

NSObject basic reflection additions.

This category extends NSObject reflection API in a minimal way.

The true Etoile reflection API is declared in ETReflection.h.

ETReflection

Mirror-based reflection for Etoile

Description forthcoming.

ETClassMirror

Mirror-based reflection API for Etoile

Description forthcoming.

ETInstanceVariableMirror

Mirror class that represents an Objective-C instance variable.

ETInstanceVariableMirror implements the collection protocol to allow ivar content to be recursively traversed when ivars are presented in a UI inspector. For example,the inspector can use an outline view which makes possible to look at the "subivars" that makes up the object which corresponds to each ivar value.

If the ivar isn't an object type, the ivar is not traversable.

See also ETViewModelLayout in EtoileUI.

ETMethodMirror

Mirror-based reflection API for Etoile

Description forthcoming.

<ETClassMirror>

Mirror-based reflection for Etoile

Description forthcoming.

<ETInstanceVariableMirror>

Mirror-based reflection for Etoile

Description forthcoming.

<ETMethodMirror>

Mirror-based reflection for Etoile

Description forthcoming.

<ETMirror>

Mirror-based reflection for Etoile

Description forthcoming.

<ETObjectMirror>

Mirror-based reflection for Etoile

Description forthcoming.

<ETProtocolMirror>

Mirror-based reflection for Etoile

Description forthcoming.


Model and Metamodel

ETMultiOptionsRole

Description forthcoming.

NSDictionary (ETPropertyValueCoding)

Property Value Coding protocol used by CoreObject and EtoileUI provides a unified API to implement access, mutation, delegation and late-binding of properties.

Description forthcoming.

NSDate (ETModelAdditions)

Description forthcoming.

ETModelElementDescription

Abstract base class used by Model Description core classes.

The Model Description classes implement a Metamodel framework inspired by FAME (http://scg.unibe.ch/wiki/projects/fame).

Within this Metamodel, ETModelElementDescription provide basic abilities:

ETEntityDescription, ETPropertyDescription and ETPackageDescription all inherit from ETModelElementDescription, can be registered inside a model description repository using -[ETModelDescriptionRepository addDescription:] .

Conceptual Model

This metamodel is based on the [FM3 specification](http://scg.unibe.ch/wiki/projects/fame/fm3).

For a good introduction, read the paper [FAME — A Polyglot Library for Metamodeling at Runtime](http://www.iam.unibe.ch/~akuhn/d/Kuhn-2008-MRT-Fame.pdf)

We support the entire FM3 specification with some minor adjustements, however the tower (model, metamodel, meta-metamodel) is not explicitly modeled in the API unlike in FAME.

The MSE serialization format is also unsupported. In the future, we will provide our own exchange format based on JSON.

FAME Terminology Change Summary

Those changes were made to further simplify the FAME terminology which can get obscure since it overlaps with the host language object model, prevent any conflict with existing GNUstep/Cocoa API and reuse GNUstep/Cocoa naming habits.

We list the FAME term first, then its equivalent name in EtoileFoundation:

FM3.Element
ETModelElementDescription
FM3.Class
ETEntityDescription
FM3.Property
ETPropertyDescription
FM3.RuntimeElement
ETAdaptiveModelObject
attributes (in Class)
propertyDescriptions (in ETEntityDescription)
allAttributes (in Class)
allPropertyDescriptions (in ETEntityDescription)
superclass (in Class)
parent (in ETEntityDescription)
package (in Class)
owner (in ETEntityDescription)
class (in Property)
owner (in ETPropertyDescription)

For the last two points, we can consider FM3.Property.class and FM3.Class.package have been merged into a single FM3.Element.owner property in EtoileFoundation since they were redundant.

Changes to FAME

In EtoileFoundation, there is a -owner property that represents either:

While in FAME, owner is a derived property and these various owner kinds are each modeled using a distinct property (class in FM3.Property and package in FM3.Class).

In FAME, container implies not multivalued. In EtoileFoundation, multivalued now controls whether a property is a container or not, and -isContainer is now derived.

Unlike FAME, EtoileFoundation does support overriding property descriptions. This is mainly useful, for read-only properties overriden as read-write in subclasses/subentities.

Additions to FAME

-isPersistent has been added to control the persistency, how the interpret the metamodel and its constraints for the framework providing the persistent support is up to this framework. For now, some CoreObject constraints are harcoded in the metamodel.

-isReadOnly has been added to support set-once properties.

-itemIdentifier has been added as a mean to get precise control over the UI generation with EtoileUI.

Removals to FAME/EMOF

NamedElement and NestedElement protocols don't exist explicitly.

Property description names can be in upper case (FAME was imposing lower case as a constraint).

Metamodel Constraint Summary

Metamodel constraints are checked in -checkConstraints: , while model constraints are validated in -[ETPropertyDescription validateValue:forKey:] .

Note: In the future, -checkConstraints: should probably be delegated to -[ETPropertyDescription validateValue:forKey:] in the meta-metamodel.

If we sum up the changes to the FAME conceptual model, for the new ETPropertyDescription, the metamodel constraints are:

  • composite is derived from opposite.container
  • derived and not multivalued implies container
  • derived implies not persistent
  • if set, opposite.opposite must be self (i.e. opposite properties must refer to each other)
  • if set, opposite.owner must be type
  • owner must not be nil
  • type must not be nil

At the model level, the semantics are:

  • container property chains may not include cycles (could be turned into a model constraint)
  • any multivalued property defaults to empty
  • boolean properties default to false
  • non primitive properties default to nil
  • string and number properties do not have a default value (could be changed later)

Since the metamodel is the model of the meta-metamodel, the model semantics apply to the metamodel too. For model constraints that apply to the metamodel, the validation would be done at the meta-metamodel level with -[ETPropertyDescription validateValue:forKey:] , rather than at the metamodel level with -checkConstraints: .

For the new Entity Description, the metamodel constraints are:

  • parent is not nil
  • parent must not be a primitive, unless self is a primitive
  • parent chain may not include cycles (could be removed, this comes from 'container property chains may not include cycles' in the model semantics of ETPropertyDescription)
  • package must not be nil
  • allPropertyDescriptions is derived as union of propertyDescription and parent.allPropertyDescriptions
  • propertyDescriptions replaces parent.propertyDescriptions in allPropertyDescriptions
  • allPropertyDescriptions must have unique names

ETValidationResult

A model validation result returned by the metamodel.

Helper class used as the return value of a validation, rather than passing pointers to objects and modifying them.

ETPropertyDescription

Description of an entity's property.

A property description represents either an attribute or a relationship that belongs to an entity. Whether a property represents an attribute or relationships depends on the -type (the entity description for the propery value).

For a primitive type (see -[ETEntityDescription isPrimitive] ), the property is an attribute. For a non-primitive type, it is a relationship. For more explanations, -isAttribute and -isRelationship .

Conceptual Model

For a Metamodel overview, see ETModelElementDescription.

Model Description

ETPropertyDescription provides a large number of properties to describe the model, these properties can be split into three categories:

Model Specification
Properties to describe new and existing model and metamodel (the FAME-based metamodel)
Persistency Specification
Properties to describe persistent model and persistency rules (can be leveraged or not by a Persistency framework e.g. CoreObject)
Model Presentation Specification
Properties to describe model presentation in the UI, and model-driven generation (can be leveraged or not by a UI or Model Generation framework)

The Model Specification properties must be edited to get working metamodel.

Both Persistency and Model Presentation Specifications are optional. These additional specifications are usually generic enough to be reused by Persistency and UI frameworks other than CoreObject and EtoileUI.

Warning: For now, CoreObject validation rules are hardcoded into -[ETPropertyDescription checkConstraints:] , and this limits the possibility to reuse the Persistency Specification without CoreObject.

Additional properties or specification can be added by subclassing ETPropertyDescription. In the future, we will probably support extending the metamodel dynamically at run-time too.

Role and Validation

A role can be set to provide validation rules that describe attribute or relationship constraints in a particular metamodel. The role must be compatible with the current -type. For example, when -isRelationship is NO, setting a ETRelationshipRole will cause a warning in -checkConstraints .

The validation is delegated to the role by -validateValue:forKey: .

Multivalues Both attributes and relationships can be univalued or multivalued. A multivalued relationship is a too-many relationship, while a univalued relationship is a to-one relationship. A multivalued attribute is a value object collection (multivalued relationships are entity object collections).

Late-Bound References

For easily creating property descriptions that refer to each other or entity descriptions, without worrying about the dependencies accross all the model element descriptions, ETPropertyDescriptions includes properties such as -setOppositeName: or -setTypeName: that can be used to refer to other ETModelElementDescription objects by their -name or -fullName .

When all these related descriptions are added to a repository with -[ETModelDescriptionRepository addUnresolvedDescription:] , -[ETModelDescriptionRepository resolveNamedObjectReferences] can be called to resolve the name references to their real objects.

For example, the -opposite is set based on the ETPropertyDescription object returned by -[ETModelDescriptionRepository descriptionForName:] for -oppositeName .

For properties descriptions added to entity descriptions returned by +[NSObject newEntityDescription] , all these model element descriptions are collected and resolved in the main repository. For other repositories or entity descriptions created outside of +[NSObject newEntityDescription] , you must call -[ETModelDescriptionRepository resolveNamedObjectReferences] manually.

ETModelDescriptionRepository

Repository used to store the entity descriptions at runtime.

Each repository manages a closed model description graph. Model element descriptions present in a repository must only reference objects that belong to the same repository.

The repository contains three type of element descriptions:

  • ETPackageDescription
  • ETEntityDescription
  • ETPropertyDescription

Main and Additional Repositories

A main repository is created in every tool or application at launch time. The +mainRepository is a special repository that automatically contains the entity descriptions provided through +[NSObject newEntityDescription] , that got collected in the NSObject class hierarchy when the repository is created.

Additional repositories can be created. For example, to store variations on the main repository data model.

You can collect entity descriptions provided through +[NSObject newEntityDescription] in additional repositories with -collectEntityDescriptionsFromClass:excludedClasses:resolvedNow:. Don't forget to call -checkConstraints: before using the repository.

Registering Model Description

To register an entity description, you must register the entity and its property descriptions, and do the same for the parent entity in case it is not registered yet.

[repo addDescription: entityDesc];
[repo addDescriptions: [entityDesc propertyDescriptions]];

[repo addDescription: [entityDesc parentEntity]];
[repo addDescriptions: [[entityDesc parentEntity] propertyDescriptions]];

// and so on

You must also register at the same time any entity description used as -[ETPropertyDescription type] or -[ETPropertyDescription persistentType] , and any property description referred to by -[ETPropertyDescription opposite] . If this last property description itself belongs to an unregisted entity, you must register this entity description as described previously and so on.

To register a package description, you must register the entities (and all the property and entity descriptions they refer to) and the property extensions in a way similar to the previous example.

If your model element descriptions contains named references (rather than explicit ones to the real objects) e.g. -[ETProprertyDescription oppositeName] , these descriptions must be added with -addUnresolvedDescription: , and -resolveNamedObjectReferences must be called once you don't need to call -addDescription: and -addUnresolvedDescription: anymore.

Note: If the entity describes a class, once registered, you usually bind it to its class as described in the next section.

Entity and Class Description Binding

By default, a repository can contain entity descriptions that apply to:

  • a prototype or a similar object (a free-standing entity is usually used with ETAdaptiveModelObject)
  • a class

For entity descriptions describing a class, the two-way binding is established with -setEntityDescription:forClass: .

If no bound entity description or class can be found, -entityDescriptionForClass: and -classForEntityDescription both attempt to return a parent entity or superclass.

Consistency Checking

Every time entity or package descriptions are added to the repository, you must check the model description graph consistency with -checkConstraints: .

It is up to you to do it, because the repository has no way to know when you are done adding descriptions and the repository content is in a coherent state that won't raise warnings.

ETAdaptiveModelObject

WARNING: This class is under development and must be ignored.

Very simple implementation of an adaptive model object that is causally connected to its description. This means that changes to the entity description immediately take effect in the instance of ETAdaptiveModelObject.

Causal connection is ensured through the implementation of -valueForProperty: and -setValue:forProperty: .

ETCPrimitiveEntityDescription

Used to describe Model description C primitives: float, BOOL, etc. See -[ETEntityDescription isCPrimitive] .

This class is used internally. You can possibly use it to support new primitives.

ETPackageDescription

Collection of related entity descriptions, usually equivalent to a data model.

A package can also include extensions to other entity descriptions. An extension is a property description whose owner doesn't belong to the package it gets added to.

For example, a category can be described with a property description array, and these property descriptions packaged as extensions to be resolved later (usually when the package is imported/deserialized).

From a Model Builder perspective, a package is the document you work on to specify a data model.

ETNumberRole

Description forthcoming.

ETRelationshipRole

Description forthcoming.

ETRoleDescription

Property Role Description classes. These allow a pluggable, more precise property description.

NSMutableDictionary (ETMutablePropertyValueCoding)

Property Value Coding protocol used by CoreObject and EtoileUI provides a unified API to implement access, mutation, delegation and late-binding of properties.

Description forthcoming.

<ETPropertyValueCoding>

Property Value Coding protocol used by CoreObject and EtoileUI provides a unified API to implement access, mutation, delegation and late-binding of properties.

Property-Value Coding allows to access properties of objects in a uniform manner, while still supporting Key-Value Coding. Key-Value Coding is similar but tends to be overriden in many subclasses. As a result, -[NSDictionary valueForKey: @"count"] doesn't return the count value, but attemps to look a value using [NSDictionary objectForKey: @"count"]. So Key-Value Coding doesn't constitute a mechanism versatile enough to introspect or access object properties. In addition, -valueForKey: doesn't accept invalid key unlike -valueForProperty: . This is important for presenting unrelated objects in a table UI (mapping properties to columns) where each object has its own property set. More generally this matters for manipulating properties of unrelated objects using the same code.

ETPropertyValueCoding protocol is usually adopted by root object classes such as NSObject and overriden in subclasses. See NSObject(Model). The basic behavior of the Property-Value-Coding is implemented in NSObject(ETModelAdditions), but few classes such as ETMutableObjectViewpoint and ETLayoutItem in EtoileUI overrides the NSObject semantic for -valueForProperty: and -setValue:forProperty: .

NSNumber (ETModelAdditions)

Description forthcoming.

NSObject (ETModelAdditions)

Description forthcoming.

NSString (ETModelAdditions)

Description forthcoming.

ETEntityDescription

A description of an entity, which can either be a class or a prototype.

Description forthcoming.

ETPrimitiveEntityDescription

A description of an entity, which can either be a class or a prototype.

Used to describe Model description primitives: object, string, boolean etc. See -[ETEntityDescription isPrimitive] .

This class is used internally. You can possibly use it to support new primitives.


Misc

NSLocking

Description forthcoming.

<MakeReleaseSelectorNotFoundErrorGoAway>

Description forthcoming.

NSData (Hash)

This NSData category provides methods for base 64 encoding and decoding the value of an NSData object and computing hashes. Uses the OpenSSL base 64 encoding and decoding functionality.

NSString (Base64)

Description forthcoming.

NSInvocation (Etoile)

NSInvocation additions.

Description forthcoming.

NSOrderedSet (ETCollection)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

ETViewpointTrait

Description forthcoming.

NSObject (ETViewpointAdditions)

Description forthcoming.

NSMutableOrderedSet (ETCollectionMutation)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSObject (ETCollectionMutationKVOSupport)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

<ETKeyedCollection>

NSObject and collection class additions like a collection protocol.

Description forthcoming.


Collection Additions

NSIndexPath (Etoile)

Additions to NSIndexPath.

Description forthcoming.

NSMapTable (Etoile)

Additions to map table class

For now, this category is limited to NSDictionary-compatibility methods.

ETKeyValuePair

A key/value association.

Key value pairs are used by EtoileUI to present and interact with keyed data structures.

If you put them in an array, the resulting data structure is roughly equivalent to an ordered dictionary or a multi-value collection. For now, ETKeyValuePair doesn't support subclassing.

NSIndexSet (Etoile)

Additions to index set classes.

Description forthcoming.

ETHistory

A generic history class which can contain arbitary entries located in the past or the future.

ETHistory keeps a history of objects of some kind. After going back in time, it can go forward again towards the most recent object. Adding an object while at a historic point will discard the forward history.

It is also possible to give ETHistory an NSEnumerator to use as a lazy source for the forward history. This way, a collection of objects can be added as a "future", replacing the current forward history.

ETHistory supports ETCollection protocol, but not ETCollectionMutation which means -[NSObject isMutableCollection] returns NO and an history won't be considered as a mutable represented object by EtoileUI.

NSArray (ETKeyValuePairRepresentation)

A key/value association.

ETKeyValuePair-related extensions to NSArray.

NSObject (ETKeyValuePair)

A key/value association.

ETKeyValuePair-related extensions to NSObject.

NSMutableIndexSet (Etoile)

Additions to index set classes.

Description forthcoming.

NSMutableDictionary (DictionaryOfLists)

NSObject and collection class additions like a collection protocol.

Extension to NSMutableDictionary for a common case where each key may map to several values.

NSArray (Etoile)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSDictionary (Etoile)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSMutableArray (Etoile)

NSObject and collection class additions like a collection protocol.

Description forthcoming.


Language Extensions

NSObject (Prototypes)

Description forthcoming.

NSObject (DoubleDispatch)

Double dispatch facility

This category provides a visitor which supports double-dispatch on all visited objects without implementing extra methods (such as accept: on the visited object side).

For a more detailed discussion, see -visit: .

Here is a visitor example:


@interface ETView : NSView
@end

@interface UIVisitor : NSObject
@end

@implementation ETView

+ (NSString *) typePrefix
{
	return @"ET";
}

@end

// To start using the visitor, instantiate a visitor and do [visitor visit: someWindow]
@implementation UIVisitor

// visitXXX methods return id, but returning void would be valid

- (id) visitWindow: (NSWindow *)aWindow
{
	NSLog(@"Visiting window %@", aWindow);
	return [self visit: [aWindow contentView]];
}

- (id) visitView: (NSView *)aView
{
	NSLog(@"Visiting view %@", aView);
	for (NSView *subview in [aView subviews])
	{
		[self visit: subview];
	}
	return nil;
}

// Show how you can include the class name prefix and how such a method has 
// priority over a method without any type prefix such as -visitView:.
- (id) visitETView: (ETView *)aSpecialView
{
	NSLog(@"Visiting special view %@", aSpecialView);
	return nil;
}

@end

NSException (ETException)

Description forthcoming.

NSObject (Trait)

Objective-C Trait

Adds traits to Objective-C, to support class composition, in addition to inheritance. Traits allow methods to be added to another class.

The trait support in EtoileFoundation is based on:

  • http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf (original and short one)
  • http://scg.unibe.ch/archive/papers/Duca06bTOPLASTraits.pdf (most recent and quite lengthy)

To get an introduction to the trait model and its various rules, you should read the short paper listed above.

Objective-C Trait Overview and Restrictions

The trait API supports both trait operators (exclusion, aliasing) and composite trait (a trait with subtraits). However there are two important restrictions:

  • the super keyword must not be used in a trait method
  • instances variables must not be accessed directly but only through accessors

If these restrictions are ignored, the code may compile, but will surely result in a buggy behavior at runtime.

With the current implementation, the limitations below should be kept in mind:

  • trait applications don't take in account class methods
  • no mechanism to declare and check non-trait methods required by trait methods (so you get a runtime exception instead)

Basic example and Terminology

To apply a trait, the basic API is +applyTraitFromClass: , and we use the terminology below:

trait class
the class which represents a trait and whose methods are called trait methods. The superclass methods are ignored if the class is used as a trait
target class
the class to which a trait class is applied to
trait application
a trait use that involves a trait class, a target class and operator-related arguments

For example:

// Traits should be applied as early as possible usually, that's why we use +initialize
+ (void) initialize
{
	if (self != [MyClass class])
		return;

	[aTargetClass applyTraitFromClass: aTraitClass];
}

Detailed Examples

Here is a more complex example that applies two subtraits (BasicTrait and ComplexTrait) to another trait (CompositeTrait), then the resulting is applied to the target class (the receiver's class).

	// -wanderWhere: from Basic method will be renamed -lost: in CompositeTrait
	[[CompositeTrait class] applyTraitFromClass: [BasicTrait class]
	                        excludedMethodNames: S(@"isOrdered")
	                         aliasedMethodNames: D(@"lost:", @"wanderWhere:")];

	[[CompositeTrait class] applyTraitFromClass: [ComplexTrait class]];

	[[self class] applyTraitFromClass: [CompositeTrait class]];

As a concrete example, collection protocols are now implemented by most classes in Étoilé frameworks through two new ETCollectionTrait and ETMutableCollectionTrait.

Trait Validation

Trait applications are memorized to support composite traits and multiple trait applications to the same target class. Each time a trait is applied, it gets validated against the trait tree already bound to the target class. This ensures operators, overriding rule and flattening property will remain valid in the new trait tree. Unlike Squeak trait support, a trait can be applied at any time.

Mixin-style Application

In addition, it's possible to apply a trait without the overriding rule (that states target class overrides trait methods), which means methods in the target class can be replaced by methods from a trait.

	// With YES, we allow the trait to override/replace methods in the target class
	[[self class] applyTraitFromClass: [BasicTrait class]
	              excludedMethodNames: S(@"isOrdered")
	               aliasedMethodNames: D(@"lost:", @"wanderWhere:")
	                   allowsOverride: YES];

Trait applications are commutative, so the ordering in which you apply traits doesn't matter… but when this mixin-style composition is used, traits are not commutative and the ordering matters. That's why we'd rather discourage its use.


Viewpoints

ETCollectionViewpoint

A proxy giving access to a model property as a mutable collection.

ETCollectionViewpoint turns a collection property belonging to a represented object into a immutable or mutable collection proxy that implements the collection protocols.

Using it as an immutable collection proxy doesn't bring a lot of benefits. However ETCollectionViewpoint can use Key-Value-Coding accessors to support mutating the collection without implementing ETCollection and ETCollectionMutation on the represented object (for the property that holds the collection).

A model object usually implements collection protocols providing access to its dominant/main collection aspect, but the represent object doesn't support these protocols to access other collections exposed as properties. ETCollectionViewpoint exposes these other collections as the main collection is usually exposed.

ETUnionViewpoint

A proxy giving access to a model property as a mutable collection.

ETCollectionViewpoint turns a collection property belonging to a represented object into a immutable or mutable collection proxy that implements the collection protocols.

Using it as an immutable collection proxy doesn't bring a lot of benefits. However ETCollectionViewpoint can use Key-Value-Coding accessors to support mutating the collection without implementing ETCollection and ETCollectionMutation on the represented object (for the property that holds the collection).

A model object usually implements collection protocols providing access to its dominant/main collection aspect, but the represent object doesn't support these protocols to access other collections exposed as properties. ETCollectionViewpoint exposes these other collections as the main collection is usually exposed.

ETIndexValuePair

An index/value association.

ETIndexValuePair doesn't support subclassing.

Note: this class is deprecated and will be removed in a next release.

ETMutableObjectViewpoint

A proxy giving access to a model property as a mutable object.

ETMutableObjectViewpoint turns an attribute or to-one relationship property belonging to a represented object, into a mutable object proxy that updates the model property with a new immutable object in reaction to -setValue:forProperty: .

ETMutableObjectViewpoint doesn't work as a mutable collection proxy for a to-many relationship property, you must use ETCollectionViewpoint instead.

Using a mutable object as ETMutableObjectViewpoint value doesn't bring a lot of benefits, but is well supported and works transparently.

For supporting editing a mutable object class, ETMutableObjectViewpoint must be subclassed. For example, for editing NSSortDescriptor, you must implement a new subclass such as ETMutableSortDescriptorViewpoint (this one is provided by EtoileUI though).

This viewpoint uses Key-Value-Observing to detect any property changes on the represented object.

<ETPropertyViewpoint>

A viewpoint protocol to represent an object property.

A property viewpoint is an adaptor that represents an object property and handles reading and writing the property value through -value and -setValue.

NSObject (ETIndexValuePair)

ETIndexValuePair-related extensions to NSObject.

Description forthcoming.

<ETViewpoint>

The base viewpoint protocol.

A viewpoint is an adaptor that exposes a value derived from a represented object and handles reading and writing the properties of this value through -valueForProperty: and -setValue:forProperty: .

The derived value object can be read and write through -value and -setValue: .

<ETViewpointMutation>

Protocol to provide a viewpoint that simulates mutability for immutable objects.

For each immutable object class, a distinct ETMutableObjectViewpoint subclass must exist.

Immutable object class that wants to support editing or mutation through a ETMutableObjectViewpoint must implement this protocol.


File Management

NSFileManager (TempFile)

Extensions to NSFileManager for creating temporary files and directories.


String Manipulation and Formatting

NSString (Etoile)

NSString additions.

Description forthcoming.

ETByteSizeFormatter

Formatter subclass to convert numbers expressed in bytes to a human-readable format.

ETByteSizeFormatter supports to format NSNumber objects up the terabyte unit as detailed in -stringForObjectValue: .

ETByteSizeFormatter is now deprecated in favor of NSByteCountFormatter, we still support it on Mac OS X for backward compatibility with 10.6 and 10.7.


High Order Messaging and Blocks

NSArray (ETCollectionHOM)

Description forthcoming.

NSObject (HOM)

A category which extends NSObject with various High Order Messages.

Description forthcoming.

NSDictionary (ETCollectionHOM)

Description forthcoming.

NSIndexSet (ETCollectionHOM)

Description forthcoming.

NSMutableArray (ETCollectionHOM)

Description forthcoming.

NSMutableDictionary (ETCollectionHOM)

Description forthcoming.

NSMutableIndexSet (ETCollectionHOM)

Description forthcoming.

NSMutableSet (ETCollectionHOM)

Description forthcoming.

NSObject (ETEachHOM)

Description forthcoming.

NSSet (ETCollectionHOM)

Description forthcoming.

<ETCollectionHOM>

Description forthcoming.

<ETCollectionHOMFilterIntegration>

The ETCollectionHOMFilterIntegration protocol defines a hook that collections can use to tie into higher-order messaging if they need special treatment of their elements.

<ETCollectionHOMIntegration>

Description forthcoming.

<ETCollectionHOMMapIntegration>

The ETCollectionHOMMapIntegration protocol defines a hook that collections can use to tie into higher-order messaging if they need special treatment of their elements.

<ETCollectionMutationHOM>

Description forthcoming.


Logging

ETTranscript

A Smalltalk-80 like Transcript implementation

A simple logging class designed for compatibility with Smalltalkers' expectations.

In the future, it may become possible to change the standard transcripts destination. ETTranscript will then take the role of an additional level of indirection.

<ETTranscriptDelegate>

A Smalltalk-80 like Transcript implementation

Protocol for transcript delegates. Store an object implementing the methods in this protocol in the thread's dictionary with the kTranscriptDelegate key and transcript messages will be sent to it instead of the standard output.


Debugging

ETStackTrace

A debug utility to record stack traces in relation to an instance.

Represents a stack trace built from an array of call stack symbols.

You usually don't need to instantiate stack trace objects directly, ETStackTraceRecorder does it.

ETStackTraceRecorder

A debug utility to record stack traces in relation to an instance.

A stack trace recorder allows to snapshot the call stack symbols and inspect these snapshots later on.

You invoke -recordForObject: to snapshot the current call stack symbols and -recordedStackTracesForObject: to get all the call stack traces recorded until now.

A stack trace recorder is very handy to debug memory management issues. e.g. You can easily discover where an over-released object was allocated in a vein similar to malloc_history on Mac OS X.

Take note that +enableAllocationRecordingForClass: is only available on GNUstep and the example detailed below doesn't apply to Mac OS X where you must use malloc_history instead.

To get meaningfull backtrace on GNUstep, you must install the GNU bin utils (e.g. binutils-dev package on Ubuntu) and configure GNUstep Base with --enable-bfd.

Be aware that the resulting gnustep-base library will be GPL-licensed and transively all the code that links it will become GPL-licensed too.

Use Case Example

For a retain/release crash, note the instance class that got double-released, then add in main() or equivalent:

[[ETStackTraceRecorder sharedInstance] enableAllocationRecordingForClass: [MyClass class]];

To prevent the instance to be deallocated, set NSZombieEnabled to YES (e.g. export NSZombieEnabled YES in the shell). Finally compile and run the program in GDB and at crash time, type on the GDB prompt:

po [[ETStackTraceRecorder sharedInstance] recordedStackTracesForObject: instance] firstObject]

Where instance is the instance address or a variable pointing on the instance. Then GDB prints the stack trace which points back to the code that allocated the instance.

You can also put a breakpoint on -[NSZombie forwardInvocation:], but take note that NSZombie doesn't respond to -recordedStackTraces (at least on GNUstep).

Thread Safety

ETStackTraceRecorder is thread-safe (not fully yet), multiple threads can invoke -recordForObject: .

NSObject (ETStackTraceRecorderConveniency)

A debug utility to record stack traces in relation to an instance.

Some conveniency methods which makes easier to work with the shared stack trace recorder instance.

For example, in GDB you can type [self recordStackTrace] to keep a trace of the current call stack.

And you can print all the stack traces recorded for the current object with 'po [[self recordedStackTraces] stringValue]'.


Uniform Type Identifier

ETUTI

A type class to represent data types and aggregate various type representations into a common type model (Uniform Type Identifier)

ETUTI objects represent Uniform Type Identifiers (UTIs), strings written in reverse-DNS notation (e.g. org.etoile.group) which are used to describe data type. UTIs support multiple inheritance to indicate that certain types are refinements of one or more parent types.

The ETUTI implementation also integrates with the Objective-C runtime. UTI's can be automatically generated for a given class, which are given the form org.etoile-project.objc.class.ClassName

EtoileFoundation provides a built-in UTI library and some class bindings (UTI supertypes to which ObjC classes conforms to). See UTIDefinitions.plist and ClassBindings.plist in the EtoileFoundation framework resources.

Additional UTIs and class bindings can be provided in third-party applications or frameworks. At launch time, ETUTI loads any UTIDefinitions.plist and ClassBindings.plist present in the main bundle and loaded frameworks, and merges the content into its runtime UTI database. You cannot redefine a UTI built into EtoileFoundation UTIDefinitions.plist.


Plug-Ins

ETPlugInRegistry

Plug-in manager class used to register new plug-ins and obtain already registered plug-ins

Each plug-in is represented by an NSMutableDictionary to which you can add your own entries as needed. The keys ETPlugInRegistry adds to this dictionary are:

bundle
NSBundle instance for this plug-in
identifier
Unique identifier for this plug-in (bundle identifier in current implementation), see -plugInIdentifierForBundle:
image
Icon (NSImage) of the plug-in (for display in toolbars etc.), see -plugInIconPathForBundle:
name
Display name of the plug-in (for display in lists, toolbars etc.), see -plugInNameForBundle:
path
Full path to the bundle.
class
Principal class (type Class) for this bundle, so you can instantiate it
instance
If -shouldInstantiatePlugInClass is YES, this contains an instance of the principal class, instantiated using alloc+init

ETPlugInRegistry is thread-safe.


Collection Protocols

ETCollectionTrait

NSObject and collection class additions like a collection protocol.

This trait implements all ETCollection protocol methods, except -content and -contentArray , for which concrete implementations must be provided by the target class.

Any method provided by ETCollectionTrait can be overriden by implementing the method in the target class.

Here is a simple example that implements a complete mutable collection API. In addition to ETCollectionTrait, it also leverages ETMutableCollectionTrait to do so.

@interface MyCollection : NSObject >ETCollection, ETCollectionMutation<
{
	NSMutableArray *things;
}

@end

#pragma GCC diagnostic ignored "-Wprotocol"

@implementation

+ (void) initialize
{
	if (self != [MyCollection class])
		return;

	[self applyTraitFromClass: [ETCollection class]];
	[self applyTraitFromClass: [ETMutableCollection class]];
}

// Omitted initialization and deallocation methods

- (id) content
{
	return things;
}

- (NSArray *) contentArray
{
	return [NSArray arrayWithArray: things];
}

- (void) insertObject: (id)object atIndex: (NSUInteger)index hint: (id)hint
{
	if (index == ETUndeterminedIndex)
	{
		[things addObject: object];
	}
	else
	{
		[things insertObject: object atIndex: index];
	}
}

- (void) removeObject: (id)object atIndex: (NSUInteger)index hint: (id)hint
{
	if (index == ETUndeterminedIndex)
	{
		[things removeObject: object];
	}
	else
	{
		[things removeObjectAtIndex: index];
	}
}

@end 

NSMutableSet (ETCollectionMutation)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSSet (ETCollection)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSCountedSet (ETCollection)

NSObject and collection class additions like a collection protocol.

NSCountedSet is a NSMutableSet subclass and thereby inherits the collection protocol methods implemented in NSSet(ETCollection).

NSIndexSet (ETCollection)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSMutableDictionary (ETCollectionMutation)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

ETMutableCollectionTrait

NSObject and collection class additions like a collection protocol.

This trait implements all ETCollectionMutation protocol methods, except -insertObject:atIndex:hint: and -removeObject:atIndex:hint: , for which concrete implementations must be provided by the target class.

Any method provided by ETMutableCollectionTrait can be overriden by implementing the method in the target class.

For a use case example, see ETCollectionTrait.

NSArray (ETCollection)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSDictionary (ETCollection)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSMutableArray (ETCollectionMutation)

NSObject and collection class additions like a collection protocol.

For NSMutableArray, -insertObject:atIndex: raises an exception when the index is ETUndeterminedIndex.

NSMutableIndexSet (ETCollectionMutation)

NSObject and collection class additions like a collection protocol.

Description forthcoming.

NSObject (ETBatchCollectionMutation)

NSObject and collection class additions like a collection protocol.

Any mutable collection can also implement the optional methods listed below.

EtoileUI will use these methods when possible.

Initially you can skip implementing them. Later, they can be implemented to speed up the communication between your model collections and the layout items that represent them at the UI level. In addition, these methods allows to react to batch insertion and removal at the model level (e.g. in reply to a pick and drop).

You are not required to implement every method when a class adopts this informal protocol.

When a collection is received in argument, the collection type can be checked to know whether the code needs to convert the collection or not, to remove or insert its content in the receiver. In most cases, the code below is a useless optimization (the else branch is good enough).

if ([[aCollection content] isArray] == NO)
{
	[personIvarArray addObjectsFromArray: (NSArray *)aCollection];
}
else
{
	[personIvarArray addObjectsFromArray: [aCollection contentArray]];
}

See NSObject+Model for other methods such as -isArray .

<ETCollection>

NSObject and collection class additions like a collection protocol.

Basic collection protocol that all collections must support. EtoileFoundation extends Foundation classes such as NSArray, NSDictionary, NSSet and NSIndexSet to adopt this protocol. EtoileUI extends NSView in the same way.

With this protocol, the collection content can be accessed and queried in various ways but cannot be mutated.

Given most protocol method implementations remains the same accross collection classes, we provide ETCollectionTrait as a reusable ETCollection implementation.

The two primitives methods are -content and -contentArray . These methods must be implemented in the collection class in all cases. See ETCollectionTrait.

When you write a new class that includes a to-many relationship, it should conform to ETCollection. If several to-many relationships exist, you should pick the dominant relationship that best represents the main content. A good hint is to pick the most recurrent way to browse the content with a UI, and the relationship traversed in such a case.

EtoileUI can automatically present collection-like content and support navigation into it when represented objects bound to ETLayoutItemGroup conform to ETCollection.

Note: In future, we will provide a viewpoint mechanism to view or traverse objects through their non-dominant to-many relationships.

<ETCollectionMutation>

NSObject and collection class additions like a collection protocol.

Additional collection protocol that all mutable collections must support. EtoileFoundation extends Foundation classes such as NSMutableArray, NSMutableDictionary, NSMutableSet, NSCountedSet and NSMutableIndexSet to adopt this protocol. EtoileUI extends NSView in the same way.

Given most protocol method implementations remains the same accross collection classes, we provide ETMutableCollectionTrait as a reusable ETCollectionMutation implementation.

The two primitive methods are -insertObject:atIndex:hint: and -removeObject:atIndex:hint: . These methods must be implemented in the collection class in all cases. See ETMutableCollectionTrait.

When you write a new class that includes a mutable to-many relationship, it should conform to ETCollectionMutation, based on the rules presented in ETCollection documentation.

EtoileUI can automatically mutate collection-like content and support turning user actions (e.g. drag an drop) into collection operations, when represented objects bound to ETLayoutItemGroup conform to ETCollectionMutation in addition to ETCollection.


UUID

ETUUID

An implementation of the Universally Unique Identifier standard.

When an ETUUID is instantiated, the underlying UUID is generated with the version 4 (aka random) generation scheme.

Take note the random scheme used on Linux and BSD platforms is based on a strong random number, unlike other platforms where a simpler random scheme is used. Which means collisions can occur on these platforms if you try to generate ETUUID in a tight loop.

You can use -isEqual: to check the equality between two ETUUID instances.

ETUUID does not have a designated initializer.

NSString (ETUUID)

UUID related additions to NSString.

NSUserDefaults (ETUUID)

Conveniency methods to easily read and write UUIDs in the default database.