2012/13

 
 

Deadline:

11.59pm Friday 14th December 2012

Detailed Requirements


The full requirements are given (below):


  1. 1.The application should be created with the following characteristics:

  2. a.Each class you create should be prefixed with your username.

  3. b.Use ARC to manage memory.

  4. c.DO NOT use storyboards.

  5. d.DO NOT use Core Data.

  6. e.DO NOT include Unit Tests.

  7. f.Start with a master-detail application project.

  8. g.Set the target device as iPad.

  9. h.Name your project NotesBrowser2012

  10. i.Select only landscape orientations for your project.


  1. 2.Loading Data: The application should start by dynamically loading the moduleDetails2012.json data file using Grand Central Dispatch, and then using this file to populate the table in the Master View.  Each cell should correspond to one of the modules and display a module code.  If the user pulls down on the master view table, this should trigger the UIRefreshControl, resulting in the data being downloaded again.  The master view’s title should be set to ”Modules”.


  1. 3.Setting and Storing the selected cell: Once the data is downloaded, if a module cell has not been selected, automatically select the first one.  Whenever a cell is selected, store this cell selection within NSUserDefaults, and use this value to select the same cell the next time the application runs.


  1. 4.Displaying Module Details: when a cell is selected, display the corresponding details in the detail view.  This includes the title of the module, the lecturer, web page URL, and details.  In addition, a tableview should be used to then list each of the entries in the moduleNotes dictionary.  The module code should appear as the title for the detail view.


  1. 5.Module Notes Table: each of the module notes cells should display the title of the notes, and include a comment on the status of the notes (consider using the cell style UITableViewCellStyleSubtitle, although you could also choose to create a custom cell). When a cell is selected, different things should happen depending on the status of the notes:


  1. a.Check to see if the notes for a cell have been downloaded, and are in the Documents Directory.  If so, display the text “Download notes”.  Pressing this cell should result in the creation of an NSOperation which will download the notes file.

  2. b.If the notes are being downloaded (i.e. an operation has been queued or is in the process of downloading), display the text “Downloading notes ...” and display a spinning UIActivityIndicatorPressing this cell should do nothing, other than deselecting the cell.

  3. c.If the notes failed to download (e.g. the network was unavailable), display the text “Failed to Download notes”.  Pressing this cell should do nothing, other than deselecting the cell.

  4. d.If the notes have been downloaded and exist in the Documents directory, display the text “View notes”.  Pressing this cell should display the notes using the QuickView Framework.


  1. 6.Downloading Notes: when the notes are to be downloaded, make use of an NSOperation and an NSOperationQueue to manage the downloads.  Set the setMaxConcurrentOperationCount of the queue to three.  If an operation has been created, ensure that a UIActivityIndicator appears in the cell, and is spinning (this can be added programmatically, or included in a custom cell).  Ensure that the UIActivityIndicator is of type UIActivityIndicatorViewStyleGray.


  1. 7.Changing Modules: One thing you will have to handle is what to do when the user changes the choice of module.  If a different module is selected, then cancel all of the operations (call the method cancelAllOperations on the operation queue, and remove all of the objects in the downloadsInProgress dictionary by using the method removeAllObjects).  As you may be indexing operations with an NSIndexPath, you want to avoid also having to worry about managing separate queues for each module.  Simply manage one for the detailView, and reset it somehow whenever the module changes


  1. 8.Accessing files in iTunes:  Ensure that the project supports iTunes File Sharing, so that the files could be accessed through iTunes if the application was running on an iPad.


  1. 9.Displaying the notes:  You should make use of the QuickLook Framework to display the notes.  Ensure that only one data item (i.e. the notes themselves) appear in the QuickLook view controller.  Present the view controller modally, using the sample code in the hints below.


The work should be based on the material presented in the KingsQueens Navigation Lab (Part B).  Additional hints will be given in the lecture material, and at the lab sessions


You can use any version of Xcode 4.4 (including the recently released Xcode 4.5) running under any version of iOS 6.


Marking Scheme

The purpose of this assignment is to demonstrate that you know how to develop native iPhone app using TableViews (and the drawing of custom cells), Modal Views, MapKit, and the ability to manipulate data structures consisting of both mutable and non-mutable combinations of NSDictionary and NSArray.  You do not need to hand in any design documentation but your code MUST be well commented so that it explains what is happening in the code.  The following marking scheme will be used to assess each submission:


  1. Split View and Tables: (40 marks total)

  2. Demonstrate an understanding of using a UISplit View Controller, by listing the modules in the master view and displaying the module information and list of lecture notes in a table within the detail view.  (20 marks)

  3. Update the module list automatically when the application first starts by using Grand Central Dispatch, and reinitiate a load whenever the UIRefresh control is used. (10 marks)

  4. Manage the initial cell selection; should be the first cell on initial use, and the saved cell on subsequent usage. (10 marks)


  1. Operation: (40 marks total)

  2. Manage the loading of notes using an NSOperation, including tracking which operations are currently queued or being executed. (20 marks)

  3. Manage the storage of the notes, so they are persistently stored once downloaded.  Ensure these are accessible from iTunes. (10 marks)

  4. Refresh the status of each lecture notes (i.e. whether it is to be downloaded, in progress, stored, or stored). (10 marks).


  1. General: (20 marks total)

  2. Adhering to all of the requirements and submission guidelines, and including all resources and sources in your submission (10 marks)

  3. Layout and Design (10 marks)


This assignment contributes 15% to your overall mark for COMP327.

The code should compile without warning or errors. 


SUBMISSION INSTRUCTIONS


Firstly, check that you have adhered to the following list:


  1. 1.Your project should be self contained within a single zip file containing all of the files in the XCode project. The file's name MUST be 'NotesBrowser2012.zip'.  Ensure that all of your source files are included in the project (hint, unpack it in a different directory and check it still builds).

  2. 2.Your project is developed within XCode, not some other language or environment.

  3. 3.Your program compiles and runs on a machine within the computer science department’s Mac Lab, either under Xcode 4.5, using the iOS SDK 6 (recently released) or an earlier version. If you have developed your code elsewhere (e.g. your own mac), ensure that it also works on our system before submission. It is your responsibility to check that you can log onto the department’s system well in advance of the submission deadline.

  4. 4.Your program does not bear undue resemblance to anybody else's! Electronic checks for code similarity will be performed on all submissions and instances of plagiarism will be severely dealt with. The rules on plagiarism and collusion are explicit: do not copy anything from anyone else’s code, do not let anyone else copy from your code and do not hand in 'jointly developed' solutions. 

 

To submit your solution you must SUBMIT IT ELECTRONICALLY, and adhere to the following instructions:


Electronic submission:

  1. Your code must be submitted to the departmental electronic submission system at: http://cgi.csc.liv.ac.uk/cgi-bin/submit.pl?module=comp327


  1. You need to login in to the above system and select ‘Assignment 3’ from the drop-down menu.  You then locate the file containing your program that you wish to submit, check the box stating that you have read and understood the university’s policy on plagiarism and collusion, then click the ‘Upload File’ button.


Work will be accepted only if it is submitted electronically following the above instructions.


Finally, please remember that it is always better to hand in an incomplete piece of work, which will result in some marks being awarded, as opposed to handing in nothing, which will guarantee a mark of 0 being awarded.  Demonstrators will be on hand during the COMP327 practical sessions to provide assistance, should you need it.


Hints

Most of what you need has already been covered in the labs or lecture notes.  The following provides a few additional hints for this assignment.


  1. 1.Start by downloading the data from the URL, and using this to populate the Master view controller.  Then, once a cell has been selected, populate the detail view and the module notes table.  Get this working before worrying about downloading any notes files.


  1. 2.The class UIRefreshControl can be used to enable “pull to reload” functionality in the Master view controller.  The following code fragment could be included in the MasterViewController’s viewDidLoad method, to create an object in the view controller.  You will need a property in the view controller to access the control (hint, call it refreshControl).  You will need to create a method for the selector (in this case, call it reloadModuleData) which is responsible for actually loading the data.  The last bit of the code fragment simulates someone “pulling” the control (which will result in the control’s activity indicator spinning around), and then the method reloadModuleData is explicitly called to start the data download.


- (void)viewDidLoad

{

    ...

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];

    [refreshControl addTarget:self

                       action:@selector(reloadModuleData)

             forControlEvents:UIControlEventValueChanged];

    [self setRefreshControl:refreshControl];

   

    // Force the table to start loading

    [refreshControl beginRefreshing];

    [self reloadModuleData];

}


  1. 3.Once the file has been downloaded (make use of dispatch_async to load the data using Grand Central Dispatch), stop the UIRefreshControl’s spinner by calling the method [[self refreshControl] endRefreshing];


  1. 4.For each of the notes file, you will see that there is a dictionary with a single key and single value, corresponding to the notes’ title and url.  Make use of the NSDictionary methods allKeys and allValues to get arrays of the keys and value.  As there is only one key and value, you can then extract this by accessing the zero’th element from the arrays.


  1. 5.For each note entry, you will need to create a filename that is (ideally) unique.  My advice would be to get the last part of the URL path, and prefix the module code.  You will also want to manage the case where the notes may not yet be available, and hence the filename could be empty or nil.  The following code fragment takes as arguments an NSDictionary containing a single note entry (i.e. one key and one value - for example:


{"Week 2, 3 and 4, Modal logic.":"http://cgi.csc.liv.ac.uk/~wiebe/Teaching/COMP521/Handouts/main7-14.4up.pdf"}


  1. and a string corresponding to the module code, and generates a file name (including its path) for the file in the Documents directory.  You can check whether the file filePath exists by calling: BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath]; if it returns true, then the file exists.


- (NSString *)generateFilePathForModuleNote:(NSDictionary *)moduleNoteDict andModuleCode:(NSString *)moduleCode {

   

    NSArray *allValues = [moduleNoteDict allValues];

    NSURL *url = [NSURL URLWithString:[allValues objectAtIndex:0]];

   

    // Check if the URL string exists

    if ([[allValues objectAtIndex:0] isEqualToString:@""]) {

        return nil;

    }

   

    // Documents directory

    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsPath = [paths objectAtIndex:0];

    NSString *filename = [NSString stringWithFormat:@"%@-%@", moduleCode, [url lastPathComponent]];

   

    // <Application Home>/Documents/myData.plist

    NSString *filePath = [documentsPath stringByAppendingPathComponent:filename];

   

    return filePath;

}


  1. 6.To make use of QuickLook, you will need to do the following things:

  2. a.Add the framework QuickLook.framework to your project (you’ve done something similar before in the WhereAmI lab).

  3. b.Import the header file <QuickLook/QuickLook.h>.

  4. c.Add the protocols <QLPreviewControllerDataSource,QLPreviewControllerDelegate> to the DetailViewController class.

  5. d.The QLPreviewController is traditionally pushed onto a navigation controller (for iPhone apps) or presented modally (for iPad apps).  To use the controller in its simplest form, simply create and present the controller modally, without worrying about implementing a “...didFinish” method. You will need to set up the delegates:


        // Display the file

        [self setFileURLforQL:[NSURL fileURLWithPath:filePath]];

       

        QLPreviewController *previewController=[[QLPreviewController alloc]init];

        previewController.delegate=self;

        previewController.dataSource=self;

        [self presentViewController:previewController animated:YES completion:nil];

        [previewController.navigationItem setRightBarButtonItem:nil];


  1. e.In the code fragment above, we turned the filePath string into a NSURL object, and stored it in the property fileURLforQL.  This is because the dataSource that the QLPreviewController uses must be either a NSURL object, or a custom object that conforms to the QLPreviewItem protocol.

  2. f.You will need to create the dataSource methods (similar to using a UITableView).   The following code fragment simply sets the number of items to preview as 1, and returns the data to be previewed as the value of the property fileURLforQL:


        // ==============================================================================================

        #pragma mark - QuickLook delegates


        - (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {

            return 1;

        }

        - (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {

            return [self fileURLforQL];

        }


  1. 7.If you want to simulate delays in loading the JSON data (to test out the UIRefreshControl), use the following URL for your data:


  1. http://www.csc.liv.ac.uk/people/trp/Teaching_Resources/COMP327/delay2.php?delay=5&url=http://www.csc.liv.ac.uk/people/trp/Teaching_Resources/COMP327/moduleDetails2012.json


Good Luck.