Hi! I’m Linda Liu, a rising junior at MIT. I’ve spent the last three months here at edX as a software engineering intern on the Mobile team, during which I’ve had the opportunity to work in a range from server side to iOS and Android development. I’d like to talk about two projects – the first, redesigning the edX access control framework, and second, exploring the React framework and its potential for edX.
Access Control Framework
This project actually started as a bug fix about course start dates for the mobile app. If a course author does not specify a start date for their course, it defaults to January 1, 2030. On the web platform, a check is performed so that a user will see “unscheduled” instead of the obviously false date. However, the mobile app does not perform an equivalent check so students were seeing that courses started in 2030.
The first potential fix that came to mind was performing a server side check in the course enrollments endpoint of the mobile API to see if the start date was the default, and having the API send a Nonevalue in that case. This fix was nice because it would require no client side changes. However, I discovered that the apps expected a timestamp from the mobile API, and crashed when that expectation was broken. Thus, a purely server side change wouldn’t work.
Talking about the potential fixes evolved into a discussion about how start date checks are done in the platform. The platform has a large function called has_access for this purpose. It takes in a user, an action, and an object, and checks if the user has the proper permissions to perform the action on the object. For example, a use of this function is to check if a student has permissions to enroll in a course. At the time, this function simply returned a boolean – True if access is granted, False if access is denied. Given that there are many reasons why access can be denied and different reasons may want to trigger different behaviors, it seemed that has_access could benefit from a return type that contains more details. The mobile API could then send the results of the has_access check to the client, which then could use the information to display an appropriate message.
The next step was designing the new return type. The new object is called AccessResponse. It is a Python object which contains a boolean equivalent to the value the original has_access would have returned, an string error code, and user and developer messages. Subclasses of it represent the errors we currently want to deal with, namely StartDateError (if the course hasn’t started for the user), VisibilityError (if the user doesn’t have the required access rights), and MilestoneError (if the user has an unfulfilled milestone). I implemented the changes in four seperate pull requests: one each to “has_access”, the mobile API, the Android client, and the iOS client. Although beyond the original scope of the bug fix, this change allows start date checks to move from the client side to the server side. As a side effect, this change makes it much easier to implement future features (such as milestones) in the mobile app. Through this work, I got to touch a lot of pieces of the edX codebase which was really cool!
React Native for iOS and React.js
My next project was more exploratory in nature, with fewer concrete goals. At edX, many features need to be developed three times – once for the web, once for iOS, and once for Android. There have been a variety of cross platform tools for mobile development with the motto “write once, use everywhere” to combat this problem, but they attempted to standardize the development too much – apps couldn’t use native platform components, so they came out feeling like glorified mobile webpages. Facebook developed a solution to this problem: a framework called React Native which enables developers to build native apps using React (a UI framework for the web).
The driving idea behind React Native is “learn once, write anywhere”. This means that platforms have different structures and styles so developers should write different applications for each, but with React Native those applications can be written with the same underlying technologies. It promises the best of both worlds – development that is efficient and similar across platforms but still has that good native feel to it. Recently, Facebook open sourced the version of the framework for iOS. The hope is that React Native (once it is also open sourced for Android) and React.js will allow developers to reuse code, and thus reduce the work needed to develop for all three platforms.
XBlocks are a good candidate for this project, because they are small modular pieces and the mobile apps currently do not have native implementations of them. Specifically, I used the drag and drop XBlock, because the interactions it uses (specifically the dragging motion) would benefit from the smooth rendering that React promises. I started out by making a simple drag and drop assessment as a stand alone iOS application, to get a feel for development with React Native. React lived up to its promise – the rendering was really smooth, and components and information were organized in a way that really made sense.
This initial experiment yielded two follow-up questions: How easily could the code could be ported into a React.js drag and drop assessment for the browser? Secondly, how easily could the drag and drop assessment be integrated with the XBlock framework such that the assessment could communicate with the server in the correct way?
I’ve spent the past few weeks working on answering these two questions. I made a web version of my iOS app, and although there wasn’t a direct iOS-to-web (React Native-to-React.js) translation of the code, information is passed around and stored in the same way, and this meant that a lot of functions could be reused. For example, all the functions that handle dragging required only a few small tweaks. This is promising because it means we can develop XBlocks tailored to different platforms but still be able to reuse the structure behind the code.
I also worked on integrating the assessment with the XBlock workbench, as that would be an important part of having it work with the platform. This involved modifying the drag and drop XBlock itself as well as implementing the correct AJAX calls from the React component such that the server knows when a student opens or attempts a problem. React made it easy to make the needed calls and now we have a React Native and React.js version of this XBlock! I’m hoping that edX will make React components a permanent part of the platform in the future.
Screenshots of the React Native Drag and Drop XBlock
Left: A user’s initial view of the problem. Right: Giving feedback via iOS alerts.
I loved that I got to work on a variety of projects this summer in terms of the technologies I used and the people I worked with. I’ve learned a lot of concrete things and also gained soft skills, such as how to communicate effectively in a software engineering team . This has been an amazing opportunity, and thanks to everyone who made it so! I’d like to especially thank my mentors, Chris Lee, Akiva Leffert, and Nimisha Asthagiri, the rest of the mobile team, and the other interns.