Today, MyState got a new feature, one that's been requested for years - Classes.
Students are now able to view their class schedule on their phones, and no longer have to carry around a screenshot of the non-mobile-formatted AccessPlus schedule:
The feature has been worked on since Spring 2015, but most of the front-end work was done in the past 4 months. The first order of business was getting APIs created.
- An API had to be created so the app could securely access student data from the 30+ year-old system that Iowa State uses for course management.
- We also needed to access the public database containing course descriptions, meeting times, and instructors.
- And finally, we needed to access yet another database that contained readable titles of courses, so something like INTR DATABS MGT SYS would look more like Introduction to Database Management Systems.
Once we worked with the web developers to obtain secure access to those databases, then my job really began.
The first thing about this feature is that it requires you to sign in with your ISU credentials to pull your class schedule. Up to this point, MyState has been completely anonymous, in that there was never a need to sign in with your credentials.
Because of security requirements, we were not allowed to accept passwords within the app. My team and I worked with the web developers to create an authentication service, which signs you in on an official login page in your browser, creates an auth token, and sends it to the app via a custom URL scheme. This worked, but was a bad experience, having to switch between the app, Safari, and back again. Thankfully, the Safari View Controller in iOS 9 came to the rescue, allowing me to keep the user in the flow of the app, while not allowing the app access to anything that was entered into the password field.
The first issue I had to tackle: The class schedule above is not formatted at all for mobile devices. How do I display all these classes to a user in a clean and concise way?
I began with the top half: the grid. The class schedule grid on AccessPlus is aligned with days of the week on the Y axis, and times of day on the X. This means that the grid is usually wider than it is tall. For a mobile device, where screen real estate is scarce, I thought it would be better to flip the axes, so days of the week went across the top.
I created a UICollectionView and subclassed a UICollectionViewLayout, overriding the
layoutAttributesForItemAtIndexPath: and other methods to create a similar grid view. I added some
UICollectionReusableViews as grid lines, and added more
UICollectionReusableViews as headers and time indicators.
The other issue I had to tackle was the white space. In the grid on AccessPlus, there is a bunch of white space, which would be filled in if I would ever take an early morning class, night class, or Saturday class (haha never). I wrote a quick algorithm that scans through a class schedule and finds the person's earliest and latest class times, and used the distance between those times to calculate the height of the
UICollectionViewCells, so they would all fit on one page and not overflow. This removed the unnecessary white space and allowed me to not hard-code in a 6am - 10pm window for classes. I also removed Saturday from the grid unless the user has a Saturday class.
I ended up with something like this:
Next, was the table below the grid. I originally planned to have only the schedule grid show, and display necessary information about classes inside the colored boxes or on the detailed page. However, I discovered that a student can be taking classes that are not scheduled (i.e. online classes or independent study). I wanted to still allow the person to see these, so I ended up having to implement a table below the grid.
There was no way that I could fit all the information in the table on the website into a
UITableView row, but I didn't have to. We have a detail page for that! I only needed to show:
- The course DEPT/Code (i.e. COM S 311)
- The course title (i.e. Design and Analysis of Algorithms)
- The meeting time(s) (i.e. TR 11:00 AM - 12:20 PM)
So I created a basic
UITableView with custom rows, which did just that.
The next issue was that the
UITableView contained very similar data, but were not tied together in any visual way. To fix this, I opted to assign colors to each class, and display the colors on both views. Also, when tapping a cell in the collection view, it would highlight the corresponding
UITableViewCell, as well as all the other meeting times of the class.
UITableView were then arranged in a half-and-half vertical stack.
The end result:
This module of the MyState app was the first module to be written in Swift. It lives within an app consisting of hundreds of Objective-C classes. I had no real issue with inter-operability between the two languages, except for a few minor glitches with Realm, the database that MyState uses for storing objects.
The Classes module of the MyState app has 4 main features: the ability to view your classes, share them, save them to your iOS calendar, and calculate your potential GPA at the end of the semester.
Sharing your schedule
When tapping the share button at the top right of your class schedule, a share sheet comes up, and you are able to share a 1000px x 650px photo of your schedule with your friends.
How was this done, you ask? Well, it was actually really easy. I created a new
UICollectionView, set it's layout to be the same as the schedule grid's, set it's
frame to be
CGRectMake(0, 0, 1000, 650), and set it's
delegate to the schedule grid's data source and delegate. I then did the following:
- Created a new
UIGraphicsImageContextwith the CGSize of
collectionView.drawViewHeirarchyInRect(frame, afterScreenUpdates: true)
- Passed the image drawn into a
Saving your schedule to the iOS calendar
This feature relied a lot on
EventKit, Apple's framework for manipulating the iOS calendar. All I had to do was add methods to each
ISUClassSection data model, which returned an
EKEvent object that details the calendar event for the class. Each
EKEvent object contains information about:
- The event's title
- Start and end times
- Repetition rules (i.e. all semester, half semester, etc)
EKEvent was then added to an
EKEventStore for the calendar the user chooses to put events into.
This feature mirrors ISU's online GPA calculator. It allows you to optionally enter in your GPA up to this point, then shows you the classes you are taking. You enter what grades you think you will receive, and it will display the GPA you would have at the end of the semester.