Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

Embed Size (px)

Citation preview

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    1/36

    Design of a Mobile Platform for Acquistion, Synthesis, andAnalysis of Programs for Exercise Instruction

    by

    James Cash

    Supervisor: Jason Foster

    April 2012

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    2/36

    Abstract

    My thesis is a design thesis, concerning the design and implementa-

    tion of a system to facilitate the acquisition, organization, and analysisof instructor-lead exercise programs, specically the program producedby Les Mills. To this end, I designed and implemented an iOS appli-cation (specically targeted to the iPhone) as well as a server backendwhich the application acquires data from. e program can be used bythe instructor to create their own custom workouts based on combina-tions of the existing exercises provided by Les Mills, while being ableto analyze their workouts to ensure that the workouts are still balancedand effective.

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    3/36

    Acknowledgements

    Much thanks to my advisor, Jason Foster for all his help, both as anadvisor and as a user of this system.anks to e Noun Project1 for their excellent library of icons.anks to Joe Conway and Aaron Hillegass for their excellent Big NerdRanch Guide: iOS Programming book, a vital resource for learning theiOS platform.

    1http://thenounproject.com

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    4/36

    2

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    5/36

    Contents

    1 Introduction 7

    2 Background 9

    3 Methods 13

    4 Results and Discussion 15

    5 Conclusion 19

    A Server API 21

    B Workout Analysis 25

    C Workout Model 31

    3

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    6/36

    4

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    7/36

    List of Figures

    2.1 Data model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

    4.1 Serverside Track Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

    4.2 Serverside Analytics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

    4.3 Client Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

    5

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    8/36

    6

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    9/36

    Chapter 1

    Introduction

    e purpose of this design thesis was to create a system which would streamline the process by which

    instructors of the Les Mills1 tness classes put together their workouts. As it currently stands, the

    company releases a physical booklet once a month containing the information for a given release,

    consisting of a series of tracks, with a variety of exercises in each track. It is very common for the

    instructors to want to mix-and-match tracks from various different releases into their own custom

    workout on a weekly basis. However, doing this manually is an extremely time-consuming process

    that is prohibitive to most of the instructors. Additionally, when creating a custom workout on ones

    own, it is very easy to inadvertently create an unbalanced workout, which may lead to the participants

    having some body part too heavily worked, another part not worked enough, or simply bored by having

    too-similar exercises right after each other.

    To solve this problem, I designed and implemented a mobile application (with a server backend)

    which will allow users to easily select tracks from a list of available releases, view the detailed information

    for each track, stitch them together into a custom workout, and nally analyze the workout for potential

    problems.

    1http://www.lesmills.com

    7

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    10/36

    8

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    11/36

    Chapter 2

    Background

    Given the design nature of the thesis, the literature review primarily consisted of researching the various

    platforms on which to base the implementation of the system.

    e implementation of the server side component of the system was fairly unconstrained, as it

    would only be communicating with the clientside component via standard HTTP methods. e pri-

    mary metric for the implementation was therefore developer familiarity and preference and secondarily

    ease of deployment. I therefore chose to use the Python programming language, as it is a system that

    I am very familiar with and have a great deal of real-world experience with. Additionally my deploy-

    ment venue of choice, Heroku1, recently added support for Python, meaning I could easily deploy

    and update the system using a familiar toolchain and workow. Furthermore, since the components

    primary role is to process data and deliver it to the client component via a simple HTTP API, a web

    framework was desired which would allow this behaviour to be implemented easily without needing a

    great deal of extraneous other functionality. e most popular Python web frameworks, Django 2 and

    Pyramid/Pylons3, were therefore rejected, as they are both intended for much more fully-featured web

    applications with very rich client user interfaces. While the Flask4 framework was attractive, ultimately

    Web.py5 was chosen, as it seemed to be the simplest framework available which provided all the requi-

    site functionality without requiring a great deal of boilerplate and allowing very exible structuring of

    1Heroku (http://heroku.com) is a popular cloud-based platform for deploying webapps.2https://www.djangoproject.com3http://www.pylonsproject.org4http://flask.pocoo.org5http://webpy.org

    9

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    12/36

    the code.

    On a more granular level, there were several important design decisions which had to be made for

    the serverside implementation, the most crucial of which was the data model used to represent the ex-

    ercise tracks and the associated workout information. While the data initially appeared to be structuredenough to allow the information to represented completely in a static and rigorous manner, examina-

    tion of other systems designed to track workout information in conjunction with deeper analysis of the

    Les Mills-provided releases showed the difficulties of this approach: e many variations on both indi-

    vidual exercises and combinations thereof are too numerous and free-form to allow for the denition

    of a static specication which can completely describe all possible workouts. erefore, the data model

    shown in Figure 2.1 was eventually decided upon. For more details on how this structure allows for a

    good compromise between structure and exibility, see chapter 3.

    Figure 2.1: Data model

    For the client component, iOS was chosen as the platform on which to develop based on severalthings. Firstly, the popularity of the iPhone and iPod Touch: Informal surveys of the instructors indi-

    cated that the vast majority of them owned at least one iOS device, while other mobile platforms such

    as Android or Windows Phone enjoy much less traction among the target demographic. Secondly,

    the development environment provided by Apple for writing iOS applications is one with which I had

    some existing familiarity, thereby allowing more time to be spent on implementing the design rather

    10

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    13/36

    than on learning to use the toolkit. Lastly, unlike an HTML5 webapp, using a native client allows for

    a seamless offline experience, which was an important design consideration.

    Within the constraints of the iOS platform, I investigated various third-party frameworks and

    toolkits, such as the OmniGroups various frameworks6

    , but ultimately decided to try to use onlythe standard iOS libraries, since the relatively straight-forward nature of the application did not seem

    to justify the inclusion of another set of dependencies nor the learning curve required to determine

    the optimal use of the libraries over the built-in facilities. erefore, I elected to use the built-in iOS

    features for the various user interface, HTTP API access, data storage and retrieval features.

    6e OmniGroup, the company behind several very popular OS X and iOS applications, has made a number of devel-oper tools and libraries available online at http://www.omnigroup.com/company/developer/

    11

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    14/36

    12

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    15/36

    Chapter 3

    Methods

    e rst phase of the design was to determine the architecture of the serverside component. As men-

    tioned above, the data model required a blend of well-dened and free-form components, with the

    model shown in Figure Figure 2.1 ultimately decided upon. is data structure was the result of a great

    deal of evolution and experimentation and changed several times over the course of implementing the

    system as new wrinkles of the way in which the workouts where represented made themselves appar-

    ent. As is clear in the diagram, there is a clear hierarchical structure to the data: A release has many

    blocks, each block has many exercises, each exercise has many moves. Within these entities, however,

    there are several elds which are essentially just free-form text, the most important of which are the

    descriptionelds on the moves and blocks. Since the description for each move and block is untyped

    and non-normalized, it allows for a great deal of exibility in describing the overall workout.

    One difficulty that this data model gave rise to was that the analytics component became difficult,

    since there was not a great deal of information about exactly what the effect of each move was on the

    performers. However, while there is no formal structure of the move descriptions, there is enough

    consistency in the form of the description that I was able to come up with some heuristic approaches

    that had excellent results. Specically, by constructing a chain of regular expressions, I was able to

    determine the nub of each move (i.e. determine if the given move is fundamentally a run, a jump,

    a punch, etc) nearly perfectly. For more detail as to how the analysis was performed, see Appendix B.

    One of the issues that arose in the implementation of the client component was the data storage and

    retrieval system. As discussed in chapter 2, I decided to use the built-in iOS features for the system.

    13

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    16/36

    As part of this decision, I elected to use Apples CoreData framework to represent and persist both

    the tracks and workouts. While this system worked well for storing the tracks, since it has a natural

    concept of hierarchical structure that meshes well with the data structure used to represent the tracks

    on the server, problems arose when implementing the workout data model. e design of the workout

    implied that each workout contains references to all of the tracks of which it consists: However, this

    relationship was very difficult to represent appropriately using the CoreData model. After spending a

    great deal of time looking into this problem, the workaround eventually discovered was to simply store

    a key in the workout for each track. is solution, while inelegant, worked well and was able to be

    abstracted over in such a way that the rest of the application was insulated from this issue. For more

    detail as to how this was done, see Appendix C.

    14

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    17/36

    Chapter 4

    Results and Discussion

    e rst part of the system to be created was the serverside component. While its ultimate purpose was

    to simply be a data store which the client would access, it also provided the opportunity to prototype the

    analytics system. erefore, while not part of the end product, the user interface the server presented

    (shown in Figure 4.1 and Figure 4.2) was still very useful in terms of experimenting with the data

    model and provided very useful information for the implementation of the client. It was in the process

    of implementing this component that the data model was nalized and where the initial concepts for

    the types of analysis (and rough ideas concerning the implementation) were concieved.

    Figure 4.1: Serverside Track Select

    15

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    18/36

    Figure 4.2: Serverside Analytics

    e implementation of the client platform was ultimately successful, in that it performed the req-

    uisite tasks of being able to acquire tracks ( 4.3b, 4.3c), organize them into workouts ( 4.3d, 4.3e), and

    analyze the workouts ( 4.3f). is process of designing a custom workout alone represents a time sav-

    ings on the order of an hour for the users over the process of manually splicing together the individual

    tracks from various releases.

    e API which the server exposes to the client is fairly straightforward (see Appendix A for details).

    It provides methods to:

    get/catalog Get the entire catalog

    get/preview Get a preview for a given track

    get/full Get the full information for a given track

    analyze/analyze Provide analysis for a given workout (not used by the client)

    analyze/recommend Recommend addtional tracks for a given workout (not used by the client)

    e client primarily uses the get/catalogand get/fullmethods. e get/catalogmethod is used

    to populate the list of available tracks the client displays when showing the available tracks to download.

    16

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    19/36

    (a) Main Interface (b) Track Catalog (c) Track Detail

    (d) Workout List (e) Workout Detail (f) Workout Analysis

    Figure 4.3: Client Interface

    eget/fullmethod is then used to download the full information for tracks which the user has opted

    to download and can then be used to create custom workouts.

    e interface of the client is presently very basic, as all of the development effort was focused

    on implementing functionality, with no spare cycles for creating artwork. All the icon artwork was

    therefore acquired from Creative Commons licenced sources, specically e Noun Project1. at

    being said, while the interface is very simple, it is nonetheless complete and usable additional interface

    work would probably be necessary to make the client a fully-edged product, it is not necessary for the

    current level of functionality.

    As discussed in the previous section, while there were some internal issues which arose, all of them

    were able to be contained well enough that none of these problems were apparent to the end-user of

    1http://thenounproject.com

    17

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    20/36

    the application. is is an excellent example of the advantages of well-thought out software design: By

    containing and abstracting over deciencies in the system, a consistent and complete product is able to

    be constructed out of an inconsistent and incomplete substrate.

    18

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    21/36

    Chapter 5

    Conclusion

    Overall, this design project was successful: A real problem was identied, a solution was carefully

    designed and successfully implemented. ere are, however, many opportunities for improvement

    remaining. In no particular order, the following features were considered but not yet added:

    Integrate the Les Mills-provided videos with the track information.

    More analytics the architecture of the analytics structure was specically designed to allow

    easy addition of more analysis engines.

    Exporting of the completed workouts to complete the cycle, it would be good if the users

    could generate a PDF and video for their custom workout.

    General enhancement of the user interface.

    e video integration was not present simply because of a lack of data splitting up the Les Mills

    videos into component tracks is a very time-consuming process to automate and was deemed to not be

    the best use of time. Similarly, the other features were just victims of time constraints and could easily

    be implemented if it was desired to publish the application as a fully-edged professional product.

    All of the code for both the server and client component are available online athttps://github.com/

    jamesnvc/Thesis-serversideand https://github.com/jamesnvc/MusashiClientrespectively.

    19

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    22/36

    20

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    23/36

    Appendix A

    Server API

    e HTTP API which the server exposes (usingweb.py) looks as follows:

    import web

    urls = (

    /, index,

    /analyze, analyze,

    /api/(.*), api,

    /(favicon.ico), static,

    /s/(.*), static,

    /authorize, auth

    )

    e essential part here are that requests can be sent to /api/which will be handled by theapiclass.

    is dispatch part of the class looks as follows:

    class Api(object):

    methods = {

    get: {

    catalog: get_catalog,

    21

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    24/36

    preview: get_preview,

    full: get_full

    },

    analyze: {

    analyze: analyze_workout,

    recommend: recommend_tracks

    },

    }

    is means, for example, a request to /api/get/catalogwill call the Api.get_catalogmethod to

    send the client the full catalog. ose methods are reproduced below:

    def get_catalog(self, _):

    Handle a request to get a list of the available tracks.

    Returns:

    A JSON list of tracks available.

    return self.to_json(self.db.select(tracks))

    def get_preview(self, args):

    Handle a request to get previews of a given track or tracks.

    Arguments:

    - args: web input with a tracks field which is a JSON list of

    track ids.

    Returns:

    A json list of track preview data.

    return self.to_json(self.db.select(

    22

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    25/36

    tracks, where=id in $ids,

    vars={ids: json.loads(args.tracks)}))

    def get_full(self, args):

    Handle a request to get full versions of a given track or tracks.

    Arguments:

    - args: web input with a tracks field which is a JSON list of

    track ids.

    Returns:

    A json list of full track data.

    track_ids = json.loads(args.tracks)

    tracks = list(self.db.select(tracks,

    where=id in $ids, vars=dict(ids=track_ids)))

    for track in tracks:

    track.blocks = list(self.db.select(blocks,

    where=track_id = $track_id,

    order=sequence,

    vars=dict(track_id=track.id)))

    for block in track.blocks:

    block.exercises = list(self.db.select(

    exercises, where=block_id = $block_id,

    order=start_time,

    vars=dict(block_id=block.id)))

    for exercise in block.exercises:

    exercise.moves = list(self.db.select(

    moves, where=exercise_id = $exercise_id,

    order=sequence, vars=dict(exercise_id=exercise.id)))

    23

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    26/36

    return self.to_json(tracks)

    24

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    27/36

    Appendix B

    Workout Analysis

    InWorkoutAnalyzer.h

    @interfaceWorkoutAnalyzer : NSObject

    + (WorkoutAnalyzer *)defaultAnalyzer;

    - (NSDictionary *)analyze:(Workout *)workout;

    - (NSString *)analyzeForOveruse:(Workout *)workout;

    @end

    InWorkoutAnalyzer.m

    - (NSString *)analyzeForOveruse:(Workout *)workout

    {

    NSArray *tracks = [workout fullTracks];

    NSComparisonResult (^cmpBlk) (id obj1, id obj2) = ^(id obj1, id obj2) {

    if ([obj1 integerValue] > [obj2 integerValue]) {

    return (NSComparisonResult)NSOrderedDescending;

    }

    if ([obj1 integerValue] < [obj2 integerValue]) {

    25

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    28/36

    return (NSComparisonResult)NSOrderedAscending;

    }

    return (NSComparisonResult)NSOrderedSame;

    };

    NSMutableArray *freqs = [[NSMutableArray alloc] init];

    for (FullTrack *track in tracks) {

    [freqs addObject:[track moveFrequencies]];

    }

    /* Compare adjacent frequency dictionaries to see if there is overlap in the

    three most frequent moves */

    NSString *fmtStr = @Tracks %d and %d may be too similiar!;

    NSMutableArray *warnings = [[NSMutableArray alloc] init];

    for (int i = 1; i < [freqs count]; i++) {

    NSDictionary *freq1, *freq2;

    freq1 = [freqs objectAtIndex:i - 1];

    freq2 = [freqs objectAtIndex:i];

    NSInteger minLen = MIN([freq1 count], [freq2 count]);

    if (minLen != 0) {

    NSIndexSet *topIdxs1 = [NSIndexSet

    indexSetWithIndexesInRange:

    NSMakeRange(0, MIN(3, [freq1 count]))];

    NSIndexSet *topIdxs2 = [NSIndexSet

    indexSetWithIndexesInRange:

    NSMakeRange(0, MIN(3, [freq2 count]))];

    NSSet *freq1Top = [NSSet

    setWithArray:[[freq1 keysSortedByValueUsingComparator:cmpBlk]

    objectsAtIndexes:topIdxs1]];

    NSSet *freq2Top = [NSSet

    setWithArray:[[freq2 keysSortedByValueUsingComparator:cmpBlk]

    objectsAtIndexes:topIdxs2]];

    26

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    29/36

    if ([freq1Top intersectsSet:freq2Top]) {

    NSLog(@Intersection between %@ and %@, freq1Top, freq2Top);

    [warningsaddObject:[NSStringstringWithFormat:fmtStr, i, i + 1]];

    }

    }

    }

    if ([warnings count] == 0) {

    return @Looks good!;

    }

    return [warnings componentsJoinedByString:@\n];

    }

    - (NSDictionary *)analyze:(Workout *)workout

    {

    NSDictionary *dict = [NSDictionary

    dictionaryWithObject:[self analyzeForOveruse:workout]

    forKey:@Overuse];

    return dict;

    }

    emoveFrequenciescode is implemented inFullTrack.mas follows:

    - (NSDictionary *)moveFrequencies

    {

    NSArray *moveDescs = [self moveTypes];

    NSMutableDictionary *freqs = [[NSMutableDictionary alloc]

    initWithCapacity:[moveDescs count]];

    for (NSString *mv in moveDescs) {

    NSNumber *val = [freqs valueForKey:mv];

    if (val == nil) {

    val = [NSNumber numberWithInt:1];

    27

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    30/36

    } else {

    val = [NSNumber numberWithInt:[val intValue] + 1];

    }

    [freqs setValue:val forKey:mv];

    }

    return freqs;

    }

    Which in turn uses themoveTypesmethod,

    - (NSArray *)moveTypes

    {

    NSMutableArray *moves = [[NSMutableArray alloc] init];

    for (NSManagedObject *blk in [self blocks]) {

    for (NSManagedObject *seq in [blk valueForKey:@sequences]) {

    for (Move *move in [seq valueForKey:@moves]) {

    [moves addObject:[move moveDescriptionNub]];

    }

    }

    }

    return moves;

    }

    is method ultimately relies on the heuristics in Move.m, which uses regular expressions to try to

    determine the fundamental type of the move in question:

    - (NSString *)moveDescriptionNub

    {

    NSError *err = nil;

    NSString *extracted = [self moveDescription];

    NSArray *regexChain = [NSArray arrayWithObjects:

    28

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    31/36

    @^[A-Z][0-9]?:\\s*,

    @\\b(L|R|F|B|OTS)\\b.*$,

    @\\s+-\\s+.*$,

    @\\[(rotate|Repeat|eye) (icon|logo)\\]\\s*,

    @^\\d+x\\s*,

    nil];

    NSRegularExpression *extractingRegex = nil;

    for (NSString *regex in regexChain) {

    extractingRegex = [NSRegularExpression

    regularExpressionWithPattern:regex

    options:0

    error:&err];

    if (err) {

    NSLog(@Error in regular expression: %@, err);

    return nil;

    }

    extracted = [extractingRegex

    stringByReplacingMatchesInString:extracted

    options:0

    range:NSMakeRange(0, [extracted length])

    withTemplate:@];

    }

    return extracted;

    }

    While very approximate, this chain of transformations has proven to be very effective on all test

    data, determining the basic type of move very successfully.

    29

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    32/36

    30

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    33/36

    Appendix C

    Workout Model

    As mentioned in chapter 3, various issues in CoreData preclude having Workout objects directly ref-

    erence their associated Track objects, forcing us to use bare ids. However, we are able to use various

    language features to abstract over this, thereby hiding this implementation detail to the rest of the

    system, as shown below:

    InWorkout.h:

    @interface Workout : NSManagedObject

    @property (nonatomic, retain) NSDate * createdAt;

    @property (nonatomic, retain) NSString * name;

    @property (nonatomic, strong) NSArray *tracks;

    - (void)removeTrackForSequence:(NSInteger)sequence;

    - (void)removeTracks:(NSArray *)tracks;

    - (void)addTrack:(FullTrack *)track;

    - (FullTrack *)trackForSequence:(NSInteger)sequence;

    - (NSArray *)fullTracks;

    @end

    InWorkout.m:

    31

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    34/36

    - (NSArray *)tracks

    {

    return [NSArray arrayWithObjects:

    [self track1Id],

    [self track2Id],

    [self track3Id],

    [self track4Id],

    [self track5Id],

    [self track6Id],

    [self track7Id],

    [self track8Id],

    [self track9Id],

    [self track10Id],

    [self track11Id],

    [self track12Id],

    nil];

    }

    - (void)setTracks:(NSArray *)tracks

    {

    for (FullTrack *track in tracks) {

    [self addTrack:track];

    }

    }

    - (void)addTrack:(FullTrack *)track

    {

    switch ([track.sequenceNumber intValue]) {

    case 1:

    [self setTrack1Id:track.trackId];

    32

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    35/36

    break;

    case 2:

    [self setTrack2Id:track.trackId];

    break;

    case 3:

    [self setTrack3Id:track.trackId];

    break;

    case 4:

    [self setTrack4Id:track.trackId];

    break;

    case 5:

    [self setTrack5Id:track.trackId];

    break;

    case 6:

    [self setTrack6Id:track.trackId];

    break;

    case 7:

    [self setTrack7Id:track.trackId];

    break;

    case 8:

    [self setTrack8Id:track.trackId];

    break;

    case 9:

    [self setTrack9Id:track.trackId];

    break;

    case 10:

    [self setTrack10Id:track.trackId];

    break;

    case 11:

    [self setTrack11Id:track.trackId];

    33

  • 8/12/2019 Design of a Mobile Platform for Acquistion, Synthesis, and Analysis of Programs for Exercise Instruction

    36/36

    break;

    case 12:

    [self setTrack12Id:track.trackId];

    break;

    default:

    NSLog(@Track with an unexpected sequence number: %@, track);

    break;

    }

    }

    Essentially, using the @property feature of the Objective-C language, we are able to implement

    methods that hide the nature of the representation of the tracks - to the consumer of this class, it appears

    that the workout object stores an array of tracks, rather than having multipletracknIdproperties.