Turning JSON objects into custom NSObjects
The correct way to check for success or failure of Cocoa (Touch) methods is 
documented in
"Handling Error Objects Returned From Methods" in the "Error Handling Programming Guide":


  Important: Success or failure is indicated by the return value of the
  method. Although Cocoa methods that indirectly return error objects in
  the Cocoa error domain are guaranteed to return such objects if the
  method indicates failure by directly returning nil or NO, you should
  always check that the return value is nil or NO before attempting to
  do anything with the NSError object.


Which means that the result of

NSString *fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&amp;error];


should be checked with

if (fileContents == nil) { // Not: if (error) { ...
    NSLog(@"Error reading file: %@", error.localizedDescription);
}


And you should also use the error parameter and check the result of 

NSArray *rawExhibits = (NSArray *)[NSJSONSerialization JSONObjectWithData:[fileContents dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL];


The explicit cast to (NSArray *) is not necessary because the method
returns id and that can be assigned to any Objective-C object pointer.

Actually your method to read the JSON data is too complicated: The file
contents is first read into a string (using some encoding) and then converted to back to data (using the same encoding).
This can be simplified by reading the file into data in the first step:

NSData *jsonData = [NSData dataWithContentsOfFile:filePath];


You also have to decide what to do if reading the JSON data fails.
Just logging the error is not sufficient because then the program will
crash later.



The parameter naming in your init method

-initWithExhibitName:exhibitType:


seems a bit too verbose to me. It is clear from the class name W5BExhibit
that the object is some "exhibit", so I would shorten that too

-initWithName:type:




Adding new properties to your object class and the JSON file currently
requires a new init method with more arguments. 
This can be greatly simplified using "Key-Value Coding" if you use the exact property names of your custom class as keys in the dictionary.

So assuming that W5BExhibit is defined as

@interface W5BExhibit : NSObject
@property(copy, nonatomic) NSString *name;
@property(copy, nonatomic) NSString *type;
@end


the JSON data should look like

[
  {"name":"Tennis Ball Launchers",
  "type":"Forces"},

  {"name":"Magnetic Hot Plates",
  "type":"Magnetism"},

  ...
]


Then you can create an object from a dictionary with

-(instancetype)initWithDictionary:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}




self.allExhibits = [[NSArray alloc] initWithArray:myItems];


can be simplified to

self.allExhibits = [myItems copy];




The complete code then looks like this (where I have renamed some variables,
this might be a matter of personal taste):

// Read JSON data into array
NSError *error;
NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"json"];
NSData *jsonData = [NSData dataWithContentsOfFile:jsonPath];
if (jsonData == nil) {
    // handle error ...
}
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&amp;error];
if (jsonArray == nil) {
    // handle error ...
}

// Create custom objects from JSON array
NSMutableArray *items = [[NSMutableArray alloc] init];
for (NSDictionary *dict in jsonArray) {
    W5BExhibit *exhibit = [[W5BExhibit alloc] initWithDictionary:dict];
    [items addObject:exhibit];
}
self.exhibits = [items copy];