Development Work Spring, Summer 2018 and Spring 2019 - RITAccess/accessmath GitHub Wiki

AccessMath

Directed Study (Spring 2019)

Mohammad Rafique


Issues Worked/Covered as part of this directed study (along with bugs listed below):

• Adding Images and Text #197 • Integrate note models #186 • Potential "Advanced Search" filtering icon needed #179 • Save translation position of minimized/maximized notes #159

Changesets on GitHub:

#18d37a9 and #280c1d4

Wiki Link:

https://github.com/RITAccess/accessmath/wiki

Major implementations:

1. Core Data Stack implementation switched from AMLecture to AccessLectureAppDelegate.

All managed object contexts and models are created in AccessLectureAppDelegate class instead of AMLecture class. This change is because the context needs to be accessed from several other controllers as we use lecture notes and other lecture data from many other controllers. Each lecture needs its own persistent store, thus whenever user switches from one lecture to other lecture, we compare the current persistent store with the current lecture. If the lecture is changed, then the comparison fails and create a new persistent store. And the respective model and context gets updated which is used by the switched lecture. To compare the persistent stores, the current “lecture” (of type AMLecture) is sent as a parameter to the managed object context method, so that if the persistent store has current lecture data file, then it returns the current managed object context. Otherwise, it creates a new persistent store.

Below are the method signatures created as part of Core Data Stack in AccessLectureAppDelegate.m:

- (NSManagedObjectContext *)managedObjectContextForLecture:(AMLecture*)lecture

- (NSManagedObjectContext *)managedObjectContext

- (NSManagedObjectModel *)managedObjectModel

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator

Context Saving: Below are the scenarios where context is saved to the file system: • Context is saved whenever user switches from one lecture to other lecture. • When hit Back button from NoteShuffleViewController to LectureViewContainer. • When hit ‘Save’ button on LectureViewContainer screen. • When hit Back button from LectureViewContainer to OpenViewController.

2. Lecture Search Functionality:

Added action to the Search (magnifying glass icon) button to search the lectures. When user clicks on Search button, it will display an alert box with a text field and two buttons (‘Cancel’, ‘OK’). There was a variable named _‘currectPath’ to store the path of Documents appended to Tilde (points to local storage of device/simulator). A new variable _‘currectPathWithSearchText’ has been created as part of this implementation.

In the search method (- (void)search), the text entered in alert’s text box is appended to _“currectPath” separated by a comma and is stored in _“currectPathWithSearchText”. This _“currectPathWithSearchText” variable is used when fetching the documents (lecture files) in AMIndex class and are basically filtered based on the search text appended to _currectPath (Documents location).

There is a “Clear Search” button added on top right of the navigation bar. When clicked on it, an action method is called “- (IBAction)clearSearch:(id)sender”. This resets the _currectPathWithSearchText to nil and _currectPath is used to load the document previews (using loadDocumentPreviews) method which removes the filtering of lectures and display all lectures.

“Clear Search” button is enabled when applied search criteria and is reset to disabled state, when there is no search criteria applied.

3. Adding Notes, Images and Text to Notes:

On NoteShuffleViewController, added a New (or Plus) icon at the top right of the navigation bar. When clicked on it, it displays an alert saying to select type of note the user wants to create. There are two types: Note and NoteTakingNote.

For now, a new paper gets created when clicked on “Note” and no action implemented on “NoteTakingNote”. The new paper creation on screen is handled in MoreShuffle class. In method “-(void)newPaper”, all note properties are created with a new note ID for each node. A variable of type SKNode is created which acts as the note and the note properties are assigned to it as its userdata. The newly created ID is stored such that it can be used in creating new ID for new paper/note.

Once the note is opened, added features to add/view up to four images in each note and the text in the note. To add the images, the Note model has been updated to store these images in BLOB format.

In NewNotesViewController class, added methods to add images to the notes and the text to the notes. For each image adding, there is a separate method. Similarly, for viewing each image, there is a separate method available. When clicked on Add Image button, it displays an alert asking user to choose an option from taking a picture using camera or selecting a photo from the gallery. Based on user choice, respective method is called. Below are the method signatures:

-(void)takePhoto

-(void)choosePhoto

Below are the methods to add images:

- (IBAction)addImage:(id)sender

- (IBAction)addImage2:(id)sender

- (IBAction)addImage3:(id)sender

- (IBAction)addImage4:(id)sender

Below are the methods to view the images (when clicked on View Image button):

- (IBAction)viewImage:(id)sender

- (IBAction)viewImage2:(id)sender

- (IBAction)viewImage3:(id)sender

- (IBAction)viewImage4:(id)sender

Finally, there is a ‘Save’ text button added at the top right of the navigation bar in NewNotesViewController class. When clicked on it, it displays an alert box that has a text field to capture the note title. This note title can be used in future to filter the notes within a lecture. When clicked OK, it saves the notes to the context and dismisses the view controller and goes back to NoteShuffleViewController class.

Note: The notes are not saved to the file system as the context is not saved at this step, until user goes back to LectureViewContainer screen or hit the Save button on LectureViewContainer screen.

4. Saving the position of notes:

Whenever a note is created, the default position we assign to it is x=450, y=500. We use Core Graphics framework in working with various user defined element creations/drawing.

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

We use the above method which is called when the touches on screen are moved to save the new location. When a note is dragged from one position to other, then we take the new points of note and assign them to the position property of the note. All these note properties saved in the context which ultimately saves in the local sqlite file. Thus, the positions are retained even if the application instance is closed and re-opened.

Issues/Bugs fixed:

(i) Core Data stack doesn’t update

  • This issue is fixed

Problem: The persistent store URL to create the managed object context was hardcoded to some value, and it used to only take the hardcoded store every time irrespective of which lecture we are in.

Fix: Created a new method replacing the existing managed object context method as follows:

- (NSManagedObjectContext *)managedObjectContextForLecture:(AMLecture*)lecture

upon existing method

- (NSManagedObjectContext *)managedObjectContext

Using the newly added method, we can send the lecture (AMLecture) object to the method, using which we check and set the correct persistent store to the context. The old method is used only when saving the context of previous lecture in case of lecture switch by the user.

(ii) Updates of a lecture notes lost when switched to a different lecture

  • This issue is fixed.

Problem: When user switches the lectures, the persistent store is updated, so as the managed object context. Thus, while switching, the previous context changes are all getting lost.

Fix: I am calling SaveContext method upon satisfying few conditions like persistent store is not null etc., before switching the lecture. Also, made sure to save the context in all possible scenarios.

(iii) Issue from GitHub #137 “Screen Cuts off in some views” is not reproducible

  • Needs review.

Since I haven’t seen any screen cutoffs during my work in this project, this issue might have fixed with the code changes done as part of my work. But it needs a review at later stages of the project and can take necessary action.

(iv) Application crashes while exiting a lecture to Open View Controller screen

  • Partially fixed. (Occurring randomly, but I have an analysis on this)

Problem: When clicked Back button from Lecture View Container screen, application crashes sometimes.

Analysis and Fix: As per my observation, for the lectures which doesn’t contain any notes in it, it is working fine. But for the lectures which have notes in it, the application is being crashed sometimes. The possible reason is that when we have notes in a lecture, we create child view controllers and add a sub view on the LectureViewContainer, thus while dismissing the view controller on going Back from the screen, I assume that the child controllers are not popped out from the parent container and thus the dismiss is not being done properly. And this is observed when there are more than 1 lectures and try switching between lectures. The root cause is still not sure. The final result and the reason for this crash is, the indexPath in OpenLectureController is getting invalid sections, which is redirecting application to create directoryViewCell instead of lectureViewCell and is trying to set the cell text using an array of directories, which are actually empty. Thus, resulting in NSRangeException.

I am checking to remove any child view controllers from parent before dismissing the lecture view container. But it only works sometimes, not always.

Temporary Fix (to stop the crash): When the indexPath section is invalid (if [indexPath item] is null), then I am forcing them to create lectureViewCell instead of directoryViewCell at an invalid position on the controller screen, making an additional lecture to be displayed (with some portion of lecture cutoff).

Code where the issue is: “OpenLectureController.m” file

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

{

`switch (indexPath.section) { 		//Invalid section, going to case 0 instead of case 1`

    `case 0:`

    `{`

        `if(![indexPath item])		//Temporary Fix – Forcing to create lectureViewCell`

        `{`

            `UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:lectureCellReuseID forIndexPath:indexPath];`

            `return [self lectureViewCellWithCell:(LoadingLectureCVC *)cell indexPath:indexPath];`

        `}`

        `UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:directoryCellReuseID forIndexPath:indexPath];`

        `return [self directoryViewCellWithCell:(DirectoryCVC *)cell indexPath:indexPath];`

    `} break;`

        
    `case 1:`

    `{`

        `UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:lectureCellReuseID forIndexPath:indexPath];`

        `return [self lectureViewCellWithCell:(LoadingLectureCVC *)cell indexPath:indexPath];`

    `} break;`

`}`

`return nil;`

}

//////////////// Actual Application Crash

- (UICollectionViewCell *)directoryViewCellWithCell:(DirectoryCVC *)cell indexPath:(NSIndexPath *)indexPath

{

`cell.title.text = _fsIndex[_currectPath stringByAppendingPathComponent:@"*"](/RITAccess/accessmath/wiki/_currectPath-stringByAppendingPathComponent:@"*")[indexPath.row]; //Out of range exception`

`return cell;`

}