CALIFORNIA STATE UNIVERSITY, NORTHRIDGE IPHONE APPLICATION DEVELOPMENT CHALLENGES AND SOLUTIONS A graduate project submitted in partial fulfillment of the requirements For the degree of Master of Science in Software Engineering By Nikolas S. Terani May 2012 The graduate project of Nikolas S. Terani is approved: ____________________________________ Dr. John Noga __________________ Date _____________________________________ Dr. G. Michael Barnes ___________________ Date _____________________________________ Dr. Robert Lingard, Chair __________________ Date California State University, Northridge ii ACKNOWLEDGEMENTS I would like to thank my father Nick Terani, mother Barbara Weitz, brother Tony Terani, and sister Tasha Terani for their loving support. I am truly blessed to have such a wonderful family. I would like to thank my friends for being such incredible people, in particular Ryan Bock for helping me to define the word friendship and Arash Mobayen for managing to stay friends with me for over thirty years. I would like to thank Lorraine Hinojosa for being such an integral part of my life and for always being there. I would like to thank Prof. Lingard for his dedication to the teaching profession. His guidance was such an important part of the completion of this project. iii Table of Contents Signature Page......................................................................................................................ii Acknowledgements.............................................................................................................iii Abstract...............................................................................................................................vi 1. Introduction.....................................................................................................................1 1.1 Problem Definition.............................................................................................1 1.2 An Agile Process.................................................................................................1 2. Review of Tools and Technologies...................................................................................4 2.1 Generic Challenges of iPhone Development......................................................4 2.1.1. User Interface...................................................................................5 2.1.2. Performance and Memory Constraints.............................................8 2.1.3. Saving State.....................................................................................9 2.1.4. Sandboxed Environment................................................................10 2.1.5. Integrating with Enterprise applications.........................................10 2.2 Objective C......................................................................................................11 2.3 Cocoa Frameworks...........................................................................................14 2.3.1. Model View Controller...................................................................15 2.3.2. Delegation...................................................................................... 15 3. Requirements Analysis...................................................................................................17 3.1 Problem Statement...........................................................................................17 3.2 User Feedback..................................................................................................17 3.3 Features............................................................................................................19 4. Design.............................................................................................................................21 4.1 Design Objective..............................................................................................21 4.2 Playlist Provider...............................................................................................21 4.3 Sequence...........................................................................................................24 4.4 Strategy Pattern in Creative Spin.....................................................................25 4.5 Performance Decisions.....................................................................................25 4.6 Diagrams..........................................................................................................27 4.6.1. Class Diagram................................................................................27 4.6.2. Integration Diagram.......................................................................28 4.6.3. Object Diagram..............................................................................29 5. Implementation..............................................................................................................30 5.1 Radio Playlist...................................................................................................30 5.2 Block Playlist ..................................................................................................30 5.3 Sequence...........................................................................................................32 6. Challenges Encountered.................................................................................................34 6.1 Learning a New Language................................................................................34 6.2 Cocoa Frameworks...........................................................................................34 6.3 View Controllers and Events............................................................................35 6.4 Memory Management......................................................................................36 6.5 Performance......................................................................................................36 iv 7. Conclusion......................................................................................................................39 References..........................................................................................................................44 Appendix A (Requirements Specification, Preliminary Design, and Initial Planning)......45 Introduction............................................................................................................45 Overall Description................................................................................................48 System Features.....................................................................................................49 Use Cases and Modules.........................................................................................58 Non-Functional Requirements...............................................................................63 Trade Study.............................................................................................................65 Change Request......................................................................................................65 Appendix B (Statistical Analysis)......................................................................................66 v ABSTRACT IPHONE APPLICATION DEVELOPMENT CHALLENGES AND SOLUTIONS By Nikolas Terani Master of Science in Software Engineering The iPhone is one of the great stories in computing history. At the time of this writing over 500,000 iPhone apps have been developed since its launch. This is undoubtedly a staggering figure. Although an interesting platform both for the societal and cultural implications this project focused on the technological challenges of iPhone development through the eyes of a living breathing iPhone application. The application developed is called Creative Spin which aimed to capture the spirit of the listening experience set forth by radio stations. The model used to develop the application was Agile by nature, using short life cycles which aimed to add on functionality through each iteration of development. Each development cycle included the traditional phases of software development: requirements vi analysis, design, implement, test, and repeat. The life cycles for development were: build out the framework for the UI, prototype the core feature, verify the prototype, design the core feature using object oriented design principles and patterns, implement the core feature, verify the core feature, conceive of new features to add to the application, integrate new feature into application, perform integration and unit testing on new feature, and finally perform UAT (User Acceptance Testing). The key technologies used to develop the application are Xcode, Interface Builder, Objective C, and the Cocoa framework. Xcode is Apple's IDE for iPhone application development. Interface Builder is an application that allows you to create the UI for an iPhone application and “wire” it into the program. Although Interface Builder is a powerful tool that undoubtedly aids in the development of iPhone applications, the UI for Creative Spin was built programmatically whenever possible to gain a better understanding of the UI frameworks provided by Apple. Objective C is an object oriented programming language that is a super set of C. Apple has referred to Objective C as its secret weapon [6]. Although the project does not aim to describe all of the unique and powerful aspects of the language and the Cocoa framework, some important points will be articulated where appropriate. vii 1. INTRODUCTION 1.1 Problem Definition Application development is a challenging process. Software engineering aims to mitigate the various challenges by developing systematic, repeatable processes that can be applied to a problem within a particular context. Much of Software Engineering aims to apply the right processes to each individual context. The size and scope of this application made an Agile process the most natural fit. Not only did the application provide the forum for applying some Agile practices but it also provided an opportunity to explore a new environment; mobile application development. With this new environment came unique challenges to overcome; learning the Objective C language, managing memory, working in the context of an embedded system, new User Interface paradigms, and insights into new solution spaces. 1.2 An Agile Process An Agile development model was followed to mirror real world development practices, allowing the project to be built as quickly and as efficiently as possible. The ultimate intention being to build a high quality application within the constraints of a graduate project. The project was broken down into distinct life cycles where each cycle was composed of the traditional phases of software development: requirements analysis, design, implementation, verification, and validation. 1 In the first cycle the goal was to determine the primary functionality of the application by laying down the framework for the user interface. By doing this the consumer can quickly accept or reject the general strategy of the application and get a good feel for determining if the main feature of the application is being exposed in the manner in which it was conceived. In the second cycle the goal was to implement a crude version of the primary feature; Radio Play. The thought for not starting with the design of the feature and the application in general was that you do not want to spend a tremendous amount of time and resources designing the application only to discover that either the limited API exposed by the Media Player or the performance and memory constraints of the iPhone environment prevent the application from viably participating in the platform. It is generally not advised to perform premature optimizations [8]. By taking this approach several benefits can emerge. The most positive outcome is the awareness that the application is feasible. If the proof of concept fails, risk assessment must be undergone to determine if there is an alternative to the straightforward approach. In other words this is when you start spending the time to design optimizations that could possibly lead to a workable solution. In this scenario you still have gained knowledge over the solution space that can aid in this process. Once the Radio Play feature was proven to be workable the third cycle began which was to design the application with an approach that would allow for flexibility in maintaining and enhancing the application. In this cycle well established object oriented design principles and patterns were followed. In the fourth cycle a new feature was introduced which was Block Play. With the completion of Block Play integration testing 2 was performed. Finally, polishing touches were put on the application, moving it closer to production ready. 3 2. REVIEW OF TOOLS AND TECHNOLOGIES 2.1 Generic Challenges of iPhone Development When developing an application, the technology and the encompassing environment in which the application is to be deployed must undoubtedly be taken into consideration. Every application has its own unique set of challenges: an audience for which it is to be received whether it be end users or the entity that contracted the work, a set of functional requirements, a technical platform on which it will run, a potential set of standards adopted by the community and the end user which are expected be adhered to, architectural and design considerations to help manifest both the business and technological goals of the application, budget and time constraints, frameworks that may or may not aid in development, etc. An iPhone application is certainly no different and special consideration must be taken due to the distinct qualities of mobile platforms. These considerations will be discussed in the this section. 2.1.1 User Interface One of the most striking aspects of the iPhone is the beautiful display. Looking at the screen sometimes you forget to pause to contemplate just how small the screen really is. With such a limited amount of real estate to work with one could imagine a world of iPhone applications with clunky user interfaces that are difficult to interact with and produce an overall negative user experience. In fact, most would agree, the opposite is 4 true. With such a limited screen size Apple has still managed to create a platform that delivers an exceptional user experience. With the smaller screens comes a need for creative User Interfaces that expose only core features. This need may be the reason so many mobile phone applications are highly regarded. The limited amount of real estate precludes the bloat that can often come with traditional applications. Often when negotiating contracts for applications the business concerns can lead to an expanded set of requirements. The more disparate the requirements are, the more difficult it can become to develop a user interface that behaves consistently and intuitively through the myriad of functionality provided. So one might say that the limited screen size is both a blessing and a curse. The small size of the screen allows for only core features because only so many features can be physically exposed through the user interface. This focus can lead to applications that do only one thing but do it very well in a consistent and straightforward manner. Despite the need for a focused set of requirements it still becomes critical to deliver those requirements both functionally and within an elegant user interface. Apple has certainly had a reputation for shining in this arena of software development, and the iPhone is no exception. To meet the challenges of the small screen size and limited size of the phone in general it did four primary things: perfect touch screen interaction while inventing multitouch gestures to replace keyboard and mouse events, create a virtual keyboard that presents itself when necessary, use an accelerometer that changes the orientation of the screen based on how the phone is being held, and develop user interface architectures for dealing with distinct application solution spaces. Adhering to a strict 5 MVC (Model View Controller) architecture Apple developed application templates which present the user interface in a uniform manner. The two primary templates are navigation controllers and tabular controllers. A classic example of a Navigation based application is the email application for the iPhone. In a Navigation based application the user interface is presented in a hierarchical fashion where each selection drills down from the broad to the specific. For example, in the mail application the broadest view is the accounts that belong to the user. If a user selects an account he/she will now see all the specific folders associated with the account. If a folder is chosen then all the specific emails residing in the folder will be chosen. Finally, if the user selects an email within a folder the final view will be presented which is the specific content of an email. The flow of this application is handled by a Navigation Controller. A tabular application uses tabs which represents distinct functionality or organization within an application. For example, in the iPod player the tabs allow you to view the data in distinct ways: by artist, by album, by songs, by playlists, etc. The iPod player uses both Tabular Controllers and Navigation Controllers to build the user interface. Theses templates not only help to solve the need to effectively use a small amount of screen space, but they also create a consistent user interface experience for the end user across distinct applications. At the same time they greatly aid in the development process by enforcing strict adherence to the MVC design pattern. This is probably a good time to point out that Apple has gone to great lengths to adhere to well established design patterns and design principles within the frameworks of the iPhone development. You will consistently find throughout the frameworks the use of the Delegation design pattern. 6 The beauty of Delegation is that you can perform customizations of classes without any real knowledge of the class that you are customizing. It is discouraged within the Apple frameworks to subclass the main controllers such as a Tabular Controller. Customizations are instead realized through the delegate object. This provides several benefits to the framework developer, the developer who uses the framework, and the end user. The framework developer can more freely make a modification to a Controller knowing that the controller is not subclassed. The developer who uses the Controller within his/her application is freed from the burden of understanding all the technical details of how the Controller is implemented. If customizations are necessary, then the developer only needs to interact with the delegate which is a much simpler class to interact with. The user benefits through standardization. Although delegates do allow for customization, they do not fundamentally alter the user experience when interacting with the specific controller. This familiarity between applications helps establish a “learn once use everywhere” idiom for the end user. In my view this is one of the primary reasons for the tremendous success of the iPhone. The highly intuitive navigation schemes that are standardized from application to application make for a truly pleasurable user experience. Although Apple has solved most the UI challenges for the application developer, it still requires the understanding of how these controllers interoperate with your application, how to customize them when necessary, when to push these controllers on and off the stack, and of course respond to the events that the user triggers within them. 7 2.1.2 Performance and Memory Constraints Another aspect of iPhone development which permeates the mobile industry in general is performance and memory constraints. Although the processing power of modern smart phones has become quite impressive, along with the available memory, much of that power and memory allocation resources are used in rendering the user interface. As a result every mobile application developer, whether developing for the iPhone or another platform, must pay close attention to the resources used by their applications. The iPhone OS does not come with garbage collection, therefore close attention must be paid to memory management to ensure memory leaks are not present within the application. If an application becomes a resource hog, it risks being terminated by the OS at any given moment. Fortunately, Objective C has a very elegant memory management model that is fairly easy to adhere to. Objective C introduces the notion of an auto-release pool. The auto-release pool guarantees that any auto-released object will not be released from memory until after the scope of the method that requests the object has been terminated. All Objective C objects that are not native to your application are auto-released objects. What this means is that you never have to worry that an object returned from a message will be released before you are finished using it. The exception to this would of course be a method native to your application that did not adhere to the memory management model set forth by Apple. With this simple and elegant concept you are only left to manage the objects you directly allocate memory for. On top of this Apple provides many convenience constructors for objects that avoid the 8 need for the programmer to allocate memory explicitly. Therefore these convenience constructors free the programmer of the burden of releasing these objects. Although there are still challenges to managing objects within Objective C, the memory management model employed makes the task far less arduous. Additionally, lazy initialization should be employed whenever appropriate to not use resources until they are actually needed [11]. 2.1.3 Saving State One of the unique challenges of mobile development is the need to be able to save the state of the application and close gracefully within a moment's notice. Users often open and close applications in ways that are difficult to conceive of or predict. Abrupt loss of power can occur at anytime due to loss of battery power. Of course the user can receive a phone call which will immediately terminate third party applications. The user's expectation is that when he/she returns to the application, state will not be lost no matter how the application was terminated. Another concern is battery life. Applications that use features such as GPS or push notifications that have a negative impact on battery life need to be conscientious as to how these features affect battery life and if the positive effect of the feature is worth the battery cost[11]. Ultimately, smart phones are embedded systems that need to be developed in as lightweight a fashion as possible. The development of the playback modes is a good illustration of how performance can permeate design decisions in the development process. This will be discussed later when a full articulation of the primary feature of the application will be presented. 9 2.1.4 SandBoxed Environment Third party iPhone applications exists in a sandboxed environment. Each application only has access to its own data. This can present unique challenges when developing applications that would naturally want access to data outside its application space. The Creative Spin application is indeed one of these applications. The application requires access to the user's music library which belongs to the iPod player's application space. Therefore the need to use the MediaPlayer API to build the application was mandatory. This presents its own set of challenges. These challenges will also be articulated when the description of the design and implementation of the playback modes are presented. 2.1.5 Integrating with Enterprise Applications An application may find a need to integrate with another application outside its own application space and even outside the mobile phone itself. Many Enterprise applications share data in a manner which is not intended for an embedded system. Large data dumps can cause an otherwise healthy application to fail. This can create the need for unique solutions as to how to transfer data from Enterprise applications into a mobile environment. 10 2.2 Objective C Objective C is a superset of the C language. It is a very compact and yet powerful language. It shares many of components of the Java language but is inspired by Small Talk's message passing architecture. One of the key aspects of the language is the lightweight dispatcher object. This object is responsible for receiving all messages sent within the application and forwarding them to the receiver (object) for which the message is targeted. However, before the dispatcher sends the message it does two things. First it determines if the object the message is targeted for is nil. If the object is nil, the message is silently discarded. This can lead to elegant designs within certain contexts like delegation for example. If the delegate object is nil the message is never sent and the customization is not performed. Secondly, it determines if the object to which the message is targeted responds to the message. If the object does not respond to the message or forward it, an exception will be thrown. Programmatically the determination can be made, with little effort, if an object responds to a message. Decisions are then processed accordingly. As an illustration of how powerful the dispatcher architecture can be let's take a look at how the dispatcher paradigm can influence the Observer Pattern favorably. With the dispatcher architecture it becomes very easy for objects to listen to the events of their choosing without the observed object having to know which objects are listening to what events. A code example will better articulate this point [6]. -(void)updateListenersUsingSelector:(SEL)sel { for ( id listener in listeners) { 11 if ([listener respondsToSelector:sel]) { [listener performSelector: sel withObject: self]; } } } In this example the object being observed iterates through its collection of observers. If the observer implements the method defined by the sel parameter then the message will be sent to the observer which executes that method. The observed is blissfully ignorant of which events the observers are listening to. Incidentally, this technique takes advantage of Objective C's use of informal protocols. Informal protocols define methods that may or may not be implemented by the class conforming to the protocol. Another key aspect of the Objective C language is that it is a dynamically typed and bound language. What this means is that the type of the object, its class, cannot be determined until runtime. Dynamic binding refers to the determination of what method to invoke on an object [10]. With this comes the notion of the anonymous type id within the language. Declaring an object to be of type id means that any object can be assigned to the pointer variable. Although this is a powerful mechanism that can lead to elegant designs that are difficult to achieve in other more restrictive languages the type id should only be used when the type of the object truly is not known until runtime [6][7]. When the type of the object is declared, such as NSString, assigning the wrong type to that pointer variable or sending a message that the object does not respond to will generate a compiler warning. In Objective C you can declare a pointer variable to be of an 12 implementation or protocol (interface) just as in Java. For example, NSArray * myObjectPointer is declaring the myObjectPointer variable to be of type NSArray. Whereas, id<SomeProtocol> myObjectPointer is declaring the array pointer variable to be an object of any type that conforms to the SomeProtocol protocol which Java programmers will be familiar with. The difference here is that by simply declaring id myObjectPointer you are now saying the myObjectPointer variable can point to an object of any type. This can be very useful when you are within a context where you have objects that need to respond to a particular message but do not fit into a neat hierarchy for inheritance or cannot be limited to a particular interface. An example can help to better articulate this point. In the Target, Action, Outlet design pattern any object can send an action (message) to any target (receiver). This pattern helps to decouple objects in the View subsystem from objects in the Controller subsystem [7]. Imagine a music player application that has multiple ways to set the volume of the music player. One view object might be a slider and the other view object may be a custom view object that imitates volume buttons on stereos. Action Method: -(IBAction)takeVolumeFrom:(id)sender { if ([sender respondsToSelector:@selector(floatValue) ]) { float newVolume = [sender floatValue]; [[self musicPlayer] setVolume:newVolume]; 13 } } In this example you can see how the anonymous type creates flexibility between the View and Controller subsystems. The two view objects, slider and custom view object, may or may not belong to the same object hierarchy or conform to the same protocol yet they send the same action message. The action method takes a view object of the anonymous type as a parameter and asks that view object for the requested volume. This illustrates how Objective C has a philosophy rooted in aspect oriented programming. The primary concern is not the type of the object but more importantly what the object does or does not do. The focus is on behavior not the class itself [6]. In this case what is important is that the view object responds to the floatValue message. This is just one example of how the flexibility of the anonymous types aids in the creation of design patterns in the Cocoa framework. In this particular case it is enabling the decoupling of the Controller subsystem from the View subsystem through the Target/Action design pattern. 2.3. Cocoa Frameworks The Objective C language is a dynamic language that aids in the execution of design patterns. Within the Cocoa Frameworks you will find many design patterns and technologies that have been built into the frameworks to aid the application developer in the development process. Two of the key over arching patterns will be discussed briefly; Model View Controller and Delegation. 14 2.3.1 Model View Controller The Model View Controller (MVC) is one of the most widely known and implemented design patterns. In some regards it is more of a design architecture than a design pattern [6]. Within iPhone application development the MVC architecture is adhered to strictly. For example, an NSButton is not actually a button. It is actually a micro MVC architecture within the over arching MVC architecture. NSButton is actually a controller for view objects. In this case the view object it controls is NSCell. Having a good understanding of MVC is an important part of the process of becoming an effective iPhone application developer. Without a solid understanding of the architecture it will become more difficult to understand the design patterns inherent within frameworks that aid in the development process such as the Observer pattern. 2.3.2 Delegation Delegation plays a vital role in iPhone application development. Delegation is built on a fundamental object oriented design principle which is to favor composition over inheritance [8][4][5]. Delegation is a design pattern which allows for customization of a class through a delegate. A delegate can be achieved through composite objects and the use of protocols (interfaces). The dynamic nature of Objective C makes for a very natural fit with Delegation. A class can default to its standardized behavior if a delegate is not present or does not respond to a particular message. One of the unique aspects of 15 Objective C is that all method invocation is handled through a dispatcher. This lightweight object is responsible for sending a method invocation (message) to the receiver (object which encapsulates the method to be called). Unlike other languages, such as Java, sending a message to nil object (as long as the object returns an object pointer reference) does not throw an exception but is silently ignored. Therefore if no delegate is present (nil) then no customization will be performed. Additionally, the language has the built in capacity through the dispatcher to determine if an object responds to a message. You can then dynamically make the determination whether or not to send a message to an object with little effort. The general design philosophy of Objective C seems to be to provide great flexibility within the language to allow the programmer to have a richer palette from which to express himself/herself. The general goal is to not protect the programmer from himself/herself (think static typing) but to enable the programmer to achieve more with less. 16 3. REQUIREMENTS ANALYSIS 3.1 Problem Statement Existing music players have only one mode for listening to playlists created by the user. This mode is commonly referred to as shuffle mode. The short fall of the shuffle mode on existing players is that it follows a random distribution model. Although this model captures the spirit of what the user is looking for, it misses the mark in one important way; repeating artists. Due to the randomized nature of the mode, it quite naturally does nothing to prevent an artist from being repeated within a short amount of time. Of course the higher proportion of tracks the artist possesses in the playlist the more likely the artist will be repeated within a short time frame. The goal of Creative Spin is to create modes which capture the spirit of radio station formatting. By emulating these modes we can leverage a proven model for success which will hopefully lead to a more pleasurable listening experience. 3.2 User Feedback The first step in developing the requirements for the project was to first perform a statistical analysis on the iPod player to determine whether the random feature was truly random. Through informal conversations with other users the general consensus was the belief that the iPhone shuffle feature was not randomized. Artist seemed to be played 17 with “too much” frequency within any given listening session. The statistical analysis bore otherwise however, strongly suggesting that indeed the shuffle feature is randomized (see Appendix B). Although the number of conversations regarding the shuffle feature's randomness were small, and certainly not worthy of painting a broad stroke of user opinion, there still might be something valuable to learn from this inaccurate assessment of the player. The first is that statistical analysis by its very nature can be unintuitive, that is, we do not innately intuit probabilities. The second is that the discipline of performing statistical calculations is a challenging endeavor that does not lend itself to on the fly calculations. And lastly is that when you start dealing with large sets of data we as human beings become less and less familiar with the data sets we are interacting with. In the case of an iPod playlist with 1,000 songs for example, how many individuals would actually know the statistical composition of each artist within the list? More importantly how many of them would even care to know? One could even argue that a playlist with 100 songs would be difficult to keep track of by rote. What, ultimately, may be interesting about this “discovery” is how it may influence a feature with this knowledge at the forefront of the software designers mind. Does a playlist truly need to be random when a user will incorrectly interpret its randomness? Can we use this deficiency in human perception when designing features that are experienced based rather than performing concrete tasks? Were the designers of the shuffle feature thinking too much like programmers as opposed to trying to derive an outcome that more aligned with current listening standards? It would be very odd indeed to hear on an independent radio station two songs played by the same artist within a short 18 period of time. Even popular radio stations that have a limited library of music still spread out the artists they play and yet the randomize shuffle feature blatantly ignores this standard. 3.3 Features This brings us to the heart and soul of the application which is to emulate an independent radio station in the playback of a playlist. The playlist would effectively represent a radio station. There are two primary modes in which the user can select to play a playlist. The first is Radio Play. Radio Play guarantees that all artists will not be played twice within a certain number of tracks during playback of the playlist. The guaranteed number of distinct artists played back is determined dynamically by the number of songs in the playlist. This distinct set of artists has been deemed the Sequence. As an illustration of how this works let's look at an example. A playlist contains twenty six artists labeled A through Z. The length of the Sequence for this playlist we shall assume to be five. Let us assume that the first song selection is by artist Y. Artist Y may not be selected for playback again until the 6 th slot or later. So if the first five artists selected are Y, X, B, E, Z then Y may not be played again until the 6 th slot, X until the 7th slot, B until the 8th slot, E until the 9th slot and Z until the 10th spot. Of course the Artist selected in the 6 th slot may not be played until the 11th slot, etc. The Sequence is then dynamic being supplied with a new artist every playback and putting an artist back into the pool where it can then be selected again. The other mode, Block Play, will 19 play two songs from an artist consecutively, before moving on to the another artist who in turn has two songs played consecutively, and so on and so forth. Both modes guarantee that no song will be played twice within a playlist unless the playlist contains more than one reference of a song. The details of how each mode was designed and implemented will be fully articulated. Through this articulation a little light will be shed on some of the challenges of developing an iPhone application. For the User Interface three primary views were developed: Playlist, Eras, and Library. The Playlist view presented all the playlists the user has on their iPhone. The Eras view, although preconceived to be partially implemented, would arrange the songs in the iPhone by decade released. Finally, the Library view is a representation of all songs on the iPhone. Please see Appendix A for a complete Software Requirements Specification of Creative Spin. 20 4. DESIGN 4.1 Design Objective The design of Creative Spin attempted to incorporate well established object oriented principles whenever possible. The primary principles focused on were: favor composition over inheritance, open for extension and closed for modification, and favor abstract types over concrete types. Of course these principles are interrelated. The common theme among these principles is flexibility. Often by following these principles one can create applications that are easier to modify and maintain. Hopefully, through the articulation of the design of the application's primary feature it will become clear as to how these principles aid in software development. 4.2 Playlist Provider The application contains a protocol (interface) called PlaylistProvider. The playlist provider protocol has one method: formatPlaylist. There are two concrete classes within the application that conform to the PlaylistProvider protocol: RadioPlaylist and BlockPlaylist. Each one of these classes format a playlist in their own unique fashion handing it back to the sender ready to be loaded into the player. RadioPlay formatting is straightforward and simple; take a playlist and randomize it. Although the MediaPlayer API for the iPod allows for a shuffle mode, which as stated previously is randomized, using this mode would have complicated the control flow of the application. Wherever 21 possible, the application seeks to remove control flow decision making. Having complicated control flow in a program is often error prone, decreases understandability, and is more difficult to maintain. To utilize the built in mode the application would have to “know” which playback mode has been selected. Based on that mode it would then need to instantiate the correct concrete implementation of the PlaylistProvider. To limit these complications the interface PlaylistProvider is programmed to instead. Every implementation has a formatPlaylist method which formats the playlist for playback. No “decisions” are made by the application. Whatever mode is selected the appropriate behavior is provided. This programming style has several benefits. One is understandability, the control flow is very simple. A mode is selected and as a result the proper implementation is set to the protocol type. To understand what each mode does one simply looks to the concrete implementation and reviews the formatPlaylist method. Additionally, there is coherence to the design. If the built in shuffle mode provided by the MediaPlayer API for Radio Play was utilized, the formatPlaylist method would in effect have to do nothing. The second is that this helps to follow the Open/Closed design principle which states, “open for extension but closed for modification”. The more code is modified the higher the probability of introducing new bugs into the system [5]. With this design there are no control flow decisions and each mode is orthogonal. If a new mode is conceived, simply create a new implementation that adheres to the PlaylistProvider protocol and you are done. If the new mode is selected then the new behavior will be realized without touching any existing code with a few minor exceptions. 22 The first exception is that the new mode selection must be offered to the user. The modes are offered by the controller that provides the view for the playlist selected. The user can dynamically select RadioPlay mode or BlockPlay mode for each playlist from within the application. This was more desirable then having it be a setting in the native Settings application provided by Apple. With this design the user can switch between any playlist mode the controller provides. As a result the new mode would need to be added to the IndividualPlaylistController's table view so the user can select it. The second change would be to add the mode to the PlaylistProviderFactory class. This class's sole responsibility is to instantiate an instance of PlaylistProvider depending on the mode selected. So of course the theoretical new mode would need to be added here. The purpose of the factory is to follow the object oriented principle of limiting the scope of changes [5]. By encapsulating the decision of which PlaylistProvider class to instantiate into a single class one limits the scope of the change when a new implementation is necessary. If this decision was not encapsulated in a single class then everywhere in the code where a PlaylistProvider is needed, the change would have to be made which could end up being several different classes. Undoubtedly having to alter code in one place as opposed to several is less error prone. The actual formatting of the playlist needs to be fast. When the user selects a playlist to play, it is expected that music playback will begin quickly. As a general rule iPhone applications must be responsive. The less responsive the application is the less likely it will be adopted by the community [11]. As a result a design decision was made to make the formatting of the playlist as undemanding as possible for the mode. Any 23 responsibility that could be delayed to a later point in the application was. This led to the creation of the Sequence protocol. The Sequence protocol's responsibility is to determine if an artist may be repeated. 4.3 Sequence The primary method of the Sequence protocol is skipArtist. The PlaylistProvider is composed of a Sequence implementation. The BlockPlaylist provider naturally is composed with a BlockSequence object and the RadioPlaylist is composed with a RadioSequence object. The Sequence is then responsible for providing customization to the PlaylistProvider implementations. Here is an example of adopting Apple's use of the delegation pattern. The Sequence object may or may augment the format of a playlist. In the case of Radio Play the Sequence customizes the randomized format by skipping artists when necessary. In the case of Block Play the Sequence also performs this customization but may not when it comes to large playlists to improve the performance of formatting in this mode. 4.4 Strategy Pattern in Creative Spin The PlaylistProvider and Sequence both resemble the Strategy Design pattern set forth by the gang of four. The Strategy Design pattern encapsulates a family of algorithms [4]. In the case of the playlist providers the encapsulated algorithm is 24 playlist formatting. In the case of the Sequence there is effectively only one but adding more requires only the implementation of a new class that encapsulates the algorithm (skip artist). One of the key components of the Strategy pattern is that behavior can be dynamically altered at runtime. At the time being each provider only uses one Sequence and therefore the decision is hardcoded through a factory method. However, if in the future it was deemed necessary for a mode to be customized in multiple ways depending on a particular context, the flexibility is there; PlaylistProvider expects an object of type Sequence and not a specific implementation and therefore can be set at runtime. As mentioned previously the type of formatting that is applied to a playlist is dynamic. Every playlist may be formatted in either Radio or Block playback modes. 4.5 Performance Decisions The motivation for having the provider composed with a Sequence is not only flexibility but also performance. The application takes advantage of the fact that songs fade into silence at different rates. Therefore it is quite natural for there to be a pause between the ending of a song and the start up of a new song. The RadioPlaylist provides the bare minimum for preparing the playlist for playback. Instead of formatting the entire playlist in a fashion that guarantees the contract of the mode, that is, no artist will be repeated within a certain selection of songs, it simply randomizes the playlist. The randomization is fast which allows for the formatted playlist to returned quickly and playback to begin shortly thereafter. Once playback begins the Sequence takes over 25 making the determination if a song selection will be permitted when the playback state changes. This event occurs when the song ends and new song begins or when a song is skipped by the user. When the event fires, the RadioPlaylist sequence determines if the song is permitted. If the song is not permitted then the song is skipped and the determination must be made again. Songs will be skipped until an acceptable selection is found. This is all done seamlessly without the user's knowledge because the user interface does not present the new song until the actual selection is made. Additionally, song selection is fast because the playlist was already randomized when handed to the player. The application simply calls the skip song method made available by the MediaPlayer API which goes to the next track in the playlist. This happens in constant time. Additionally, when the next song is presented to the Sequence, the determination if the artist can be played is fast. The Sequence only contains the artist that must be skipped. Ultimately this strategy leads to a responsive application. 26 4.6 Diagrams 4.6.1 Class Diagram <<Interface>> PlaylistProvider MPMediaItemCollection formatPlaylist() <<Interface>> Sequence BlockPlaylist ShufflePlaylist id<Sequence> sequence id<Sequence> sequence BOOL skipArtist() BlockSequence ShuffleSequence int sequenceLength NSSet artistToSkip NSArray artistToSkipIndex int sequenceLength NSSet artistToSkip NSArray artistToSkipIndex 27 4.6.2 Interaction Diagram aIndividualPlaylistController aMediaPlayerController new() aPlaylistProvider ProviderFactory aSequence getPlaylistProvider() new PlaylistProvider() new Sequence() formatPlaylist() play() aSongViewController new (aPlaylistProvider) PlaybackChangeNotification event 28 skipArtist() 4.6.3 Object Diagram aPlaylistController playlist[0] playlist[1] aIndividualPlaylistController formattedPlaylist aSongViewController sequence 29 5. IMPLEMENTATION 5.1 Radio Playlist The formatting for the Radio Play mode is quite simple; randomize the playlist. 5.2 Block Playlist In the case of BlockPlay the formatting of the playlist is significantly more complicated. The BlockPlaylist provider must order the playlist so that two distinct songs from an artist are played back to back, followed by two songs from another artist, etc. Additionally, a song must not be repeated in the playlist (unless two copies of the song are present in the playlist). An added requirement is that the order in which the artists are played through each iteration must be randomized. The last requirement for the formatting is that no artist will be included in an iteration if they do not have enough songs to meet the length of the block. As a simple illustration consider four Artists labeled A, B, C, and D where artist A has 5 songs in the playlist, artist B has 4 songs, artist C has 7 songs, and artist D has 1 song. One format outcome may look like this: 1st Iteration: randomize artist order Artist Order: B, C, A (Artist D eliminated for not meeting block length requirement) Songs remaining: B-2, C-5, A-3 30 2nd Iteration: randomize artist order Artist Order: A, C, B Songs remaining: A-1, C-3, B-0 3rd Iteration: randomize artist order Artist Order: C (Artist A and B eliminated for not meeting block length requirement) Output: [B,C,A,A,C,B,C] (Again two songs are played from each artist) To achieve this algorithm a Dictionary, which is a collection of key/object pairs often referred to as a map. The keys for the dictionary are the artists and the objects they reference are Arrays which contain the songs from each artist in the playlist. First the playlist songs are iterated over and placed in the dictionary by artist. Secondly the set of keys within the dictionary are obtained. A while loop is then used for the primary iteration of the dictionary. The first step in the while loop is to randomize the set of keys. This allows for the artists to be hypothetically played in a different order through each iteration of the playlist. The set of keys are then iterated over obtaining two songs from each artist that has two or more songs in the dictionary. Each song used is then removed from the dictionary along with any artist that does not have two or more songs left in the dictionary. If there is an artist that still remains in the dictionary, the while loop executes again. 31 5.3 Sequence The primary method of this protocol is skipArtist. Each Sequence implementation is sent this message when a nowPlayingItemChange event occurs. This event is fired when a song ends and a new song begins or when the user presses the skip button. The Sequences responsibility is to determine if the new song is eligible for playback. If yes, the song will be played; if not, the song will be skipped. To make this determination a Set and an Array are used. If the artist is in the set, the artist is not eligible and is skipped. The Array is used to index the artist for removal from the Sequence. After a certain number of playbacks the artist is removed from the Set and Array and is again eligible for playback. The key aspect of the Sequence is to determine the appropriate length of each concrete Sequence type. The Radio Play Sequence uses a logarithmic approach. The log is base 2 and is calculated from the number of songs in the playlist. Obviously this is not enough because a playlist could be light on artists but heavy on songs. In a case such as this it could be possible for the length of the sequence to be less than the number of artists in the list. To protect against this the number of artists in the playlist is determined, and if that number is greater than or equal to half the sequence length calculated by the log, the sequence length is set to be 10% of the number of artists in the list. In Block Play the sequence is simply 10% of the number of artists in the list. The number of artists in Block Play is determined when formatting the list therefore the Sequence is handed this figure as on optimization. For Block Play no artist is will be played more than once 32 before all artists who qualified for Block Play have been played. Therefore the only reason to have the Sequence intervene is in the case that the user iterates through the entire list once and continues to listen. Due to the fact that the artists are randomized in Block mode through each pass of the playlist, it is possible for an artist to end the first iteration through the playlist and begin the second iteration through the playlist. The larger the playlist the less likely this occurrence will be. For example, a playlist with one-hundred artists in it, cannot repeat an artist for at least two-hundred songs (two songs per artist). If performance constraints deemed it necessary, the randomization between iterations of the Block Playlist formatting could be forgone. In the example provided, assuming the average length of a song in the playlist was three minutes, the user would have to listen to the playlist for 10 hours consecutively before an artist could even have the possibility of being repeated within the Sequence length. 33 6. CHALLENGES ENCOUNTERED 6.1 Learning a New Language There are several prerequisites to developing an iPhone application. The first of which is to learn Objective C. Objective C is a powerful Object Oriented language that is a super set of C. Although lightweight, the dynamic nature of the language allows for implementations that would be difficult to accomplish in other languages [7]. Objective C takes a very non-evasive approach to its architecture. The developer is in some ways free to express his/her mind in any manner sought fit even if that manner results in his/her head being chopped off. This freedom leads to paradigms within the language and Cocoa framework that are unique to the environment and therefore take effort and time to digest and process. 6.2 Cocoa Frameworks There are many design patterns implemented within the frameworks of Cocoa and even built into Objective C itself. For example, the Observer Pattern is built into the Objective C language. With almost no code any object can observe any other object as long as it conforms to Key/Value defined by the framework. To be an effective iPhone developer it is important to understand the key patterns that exist within the language and frameworks. Some interactions require only a modest understanding, while others 34 require a more in depth understanding to utilize effectively. The iPhone platform adheres to Model View Controller with great vigor. With the exception of perhaps games you will undoubtedly be actively interacting with the MVC architecture set forth by Apple. Controllers and Views are strictly segregated whereas the controller can at times also be the model. It is critical to have ownership of this aspect of iPhone development. Other patterns that play a critical role are Observer, Responder Chain, Target/Action, and Delegation. 6.3 View Controllers and Events Wrapping ones arms around the flow of an iPhone application can be a bit daunting at first. A well functioning application must appropriately respond to the various events driven by the user. To respond in the right fashion there must be an adequate understanding of the various view controllers provided by the UIKit framework. View controllers are responsible for displaying views. Some controllers have delegates that allow for customization. Certain behaviors are handled for you through the provided view controllers and certain behavior must be managed. For example, with a Navigation Controller the back button will automatically pop a controller of off the navigation stack when pressed. The navigation stack is a LIFO data structure which determines which controllers view will be presented. Understanding view controllers, the views they present, the events they respond to, how delegation can be used to customize the presentation, and the stack used to manage them is critical to designing the interface 35 effectively. 6.4 Memory Management There is no automated garbage collection available in iPhone development at the present time. Therefore an application must manage its objects manually or be subject to termination by the OS. The memory management burden is greatly lessened through Apple's elegant memory management model. Despite the aid the auto-release pool and convenience constructors provided, there is still some work to be done. Understanding memory management even in this more simplified form still requires effort. Additionally memory management is directly linked to performance because there is no memory swapping in iOS [11]. 6.5 Performance The greatest challenge to overcome in the development of Creative Spin was the performance constraints. It is still open for debate whether or not this constraint was satisfactorily overcome. The primary issue that still stands is that the application has been run on the first generation 3G iPhone. This iPhone can only hold eight gigabytes of data. Over seven gigabytes of the data stored on the test phone were dedicated to songs. Nonetheless it still remains to be seen whether or not a sixty-four gigabyte iPhone 4s phone would conform to the non-functional performance requirements outlined in the 36 Software Requirements Specification (Appendix A) document. To help meet the performance constraints the application sought to delay as much processing as possible to the notification received by the application when the state of a song changes. This notification will occur when a song is skipped or when the song ends and a new songs begins. There is a variable amount of delay that occurs when a song ends due to the way a song fades into silence. The idea was that the user will not notice an increased delay caused by the determination if a song should be skipped or not. With this in mind the formatting of the playlist which occurs before playback begins should perform as little processing as possible. The user expectation is that when a playlist is selected for playback the playback should begin immediately. If the formatting takes “too” long the user may become dissatisfied with the performance of the application. In the case of Radio Play the formatting is quite simple; randomize the playlist. The time required to begin playback is almost instantaneous. The Sequence then takes the responsibility of determining if a song played should be skipped or not. Because a logarithmic approach is taken to determine sequence length (the number of guaranteed distinct artists selected) the odds of the playlist being formatted (randomized) in such a way that requires multiple skips is unlikely. This bore out in my testing where multiple skips were very infrequent. Even when a multiple skip occurred it was imperceptible during the manual test. In the case of Block play the complexity of the formatting was deemed to be necessary. On relatively large playlists the delay between formatting and playback was well within the confines of the requirements. However, on playback of the Library (all songs on the phone) the formatting approached the upper bounds of the requirements. If 37 this were to be a production release, an iPhone capable of storing a larger number of songs would have to be tested. An alternate approach could have been to begin playback immediately and then start formatting. Every song played (in the case of a skip) would be recorded and then removed from the formatted list when it returns. The formatted list would then be loaded into the player when the next playback notification event is triggered. The event would have to then check to see if the formatted playlist has been set, and if so, load it and begin playback. This would require some effort to ensure the song view controller behaved according to convention when displaying the track number in the playlist that is being played. 38 7. CONCLUSION There have been many lessons learned from this project. In the end the long hours laboring over this endeavor have led to a significant educational experience. A major part of this educational experience was interoperating with Objective C, Cocoa design patterns, and the iPhone platform. There is a lot that can be learned from developing in this application space. The first of which is their mastery over elegant designs that are both powerful and easy to use. The overarching Model View Controller architecture, the use of the Delegation pattern, the Observer Pattern built into Objective C, the Target/Action pattern aiding in the decoupling of the View and Controller subsystems, etc., all have something to teach the developer interacting with them. The primary lesson being strategies that can be lead to more flexible reusable software. Apple also provides invaluable lessons when it comes to User Experience paradigms. Developing an iPhone application keys one in to these lessons. For example, the standardization that exists across iPhone applications made by third party vendors enriches the user's experience. Once users are familiar with one application built off the Navigation Controller template they are effectively familiarizing themselves with all applications built off that template. Apple also takes a distinctive approach to user interface development on the iPhone. Their approach is to favor a longer route to a destination rather than have the user get lost along the way. For example, it is better to design a coherent user interface that requires five screens to expose a feature rather than a confusing design that only requires two screens to expose the same feature. This may 39 seem obvious but time and time again user interfaces fail in this regard. There was also much to be gained from learning a new language. What became apparent in learning Objective C was the realization that the language in which a developer works directly affects their solution space. The language itself begins to mold and shape the thought process to fit within the patterns it provides. By learning a new language the developer has a broader solution space to operate within. Ultimately programming languages and the frameworks associated with them are tools for solving problems. The more tools one is familiar with the more likely one is to come up with a reliable solution for the problem at hand. Constantly learning new programming languages is one of the key tenets of the Pragmatic Programmer's approach [12]. The “discovery” that the iPhone iPod player is indeed randomized was certainly eye opening. In general there might be a lack of focus on user behavior when it comes to developing software as opposed to programming to specifications. With good reason Software Requirements Specification rules state that requirements must be testable. It is easy to write a requirement that states the shuffle feature must be random. However, creating requirements out of the problem statement, “capture the spirit of how radio stations format music” is much harder to specify in a requirement. Ultimately can the difficulty of capturing behavior in a requirement lead us to descriptions that fall short of the actual desired behavior? It is well understood within the software engineering community the difficulties of capturing requirements. In the case of the shuffle feature did the implementation detail (randomization) drive the formation of the requirement as opposed to the requirement driving the implementation detail? Apple is greatly respected 40 in the technological world for making great products so one would be inclined to give them the benefit of the doubt. The benefit of the doubt here would be that Apple chose to make the shuffle feature randomized without restrictions for repeating artists because they believed the restriction was not necessary. As mentioned previously, the amount of user feedback for the project was limited and not worthy of drawing any conclusions. Nonetheless it would be interesting to determine how the user community rates this feature. If it can be validated that artists repeating within a short time frame is not a desired characteristic, further study may be warranted. The primary interest here would be how did a company steeped in a tradition of providing rich user experiences miss the mark on this requirement? Does it tells us something about the difficulty of specifying requirements that try to capture experience as opposed to requirements that are task oriented? For example how does one specify in requirements the statement, “capture the spirit of radio station formatting”? The first question might be, “What do you mean by radio station formatting?” After some poking and prodding the response might be, “Well, I do not want artists to repeat within a certain time frame”. Naturally the dialog would progress to inquiring about the length of that time frame. To that question the ultimate response might be, “Well, I am not sure. I guess it would depend on the length of the playlist and how many artists were in it.” The requirements analyst is left with the challenging prospect of trying to discover a specification that will meet this criteria. Ultimately the specification must be testable and something will be eventually built, but will it actually create a pleasurable listening experience? One of the new design approaches being touted within the User Experience community is to observe users 41 interacting with the software once it has been developed or better yet during the development cycle [13]. Through observation the designer can gain insight into the product that may not have been achieved otherwise. In the case of the iPod player would Apple have discovered that user's were not happy with the purely randomized nature of shuffle feature if they would have observed them using the product? Perhaps they would have noticed a frown on the user's face when an artist was played back to back on the shuffle feature? Perhaps they would have noticed that users were skipping songs with greater frequency when the artists were being repeated within a short time frame? This could potentially be an area worthy of more exploration. In regards to the Agile process followed a slight change would be made to the process if a similar endeavor were undertaken. The second cycle would have incorporated both the Radio Play and Block Play modes to gain a better understanding of the performance constraints the project was up against. As it turned out the Block mode ended up as the feature most in jeopardy of not meeting the performance requirements. By exploring this mode earlier a better understanding of the challenges facing the project could have been assessed. Additionally, alternative designs could have been considered at this stage of the project. For example, the application could have been built using Core Data. The meta data for each song could have been persisted which would have helped to free the application up from the restrictive Media Player API and the sandboxed iPod application space. The Core Data design would definitely be worth exploring as a future project. Finally, the synchronized playlist feature described in the SRS for a future release would certainly be valuable addition to the application. It would not only provide 42 a real technical challenge but also the potential to create a unique user experience. 43 References [1] Bill Dudley, Chris Adamson, iPhone SDK Development, The Pragmatic Bookshelf, c2009 [2] Joe Conway, Aaron Hillegass, iPhone Programming, The Big Nerd Ranch Guide, Pearson c2010 [3] Dave Mark, Jeff LaMarche, Beginning iPhone 3 Development, Exploring the iPhone SDK, Apress c2009 [4] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Design Patterns, Elements of Reusable Object-Oriented Software, Pearson, c1995 [5] Eric Freeman, Elisabeth Freeman, Head First Design Patterns, O'reillly c2004 [6] Bucanek, Learning Objective C for Java Developers, Apress c2009 [7] Erik M. Buck, Donald A Yacktman, Cocoa Design Patterns, Pearson c2009 [8] Joshua Bloch, Effective Java, Addison Wesley c2008 [9] Anthony I. Wasserman, Software Engineering Issues for Mobile Application Development, Carnegie Mellon c2010 [10] Stephen G. Kochan, Programming in Objective C, Addison Wesley c2009 [11] Apple iPhone Application Programming Guide, http://developer.apple.com/iphone/library/navigation/index.html , Accessed on 10th of April 2010 [12] Andrew Hunt, David Thomas, Programmatic Programmer: From Journeyman to Master, Pearson c1999 [13] Jonathan Anderson, John McRee, Robb Wilson, Effective UI, O'reilly c2010 44 APPENDIX A (Requirements Specification, Preliminary Design and Initial Planning Document ) INTRODUCTION This SRS describes the software functional and nonfunctional requirements for release 1.0 of the CreativeSpin Software system. This document is intended to be used by the members of the project team that will implement and verify the correct functioning of the system. Unless otherwise noted, all requirements specified here are high priorities and committed for release 1.0. Agile Life Cycle Plan Life Cycle Stage Feature Name Release LC-1.0 Build the UI framework 1 LC-1.1 Manually test UI Framework 1 LC-2.0 Build the Radio Play mode without design considerations. Take a lightweight approach to insure performance requirements can be met. 1 LC-2.1 Manually test Radio Play to 1 ensure performance requirements are being met. LC-3.0 Design CreativeSpin interfaces and classes 1 LC-4.0 Implement Radio Play 1 LC-4.1 Create unit tests for Radio Play 1 LC-5.0 Implement Block Play 1 LC-5.1 Create Unit tests for Block Play 1 LC-6 Perform manual integration 1 testing driven by UI events. LC-7 Perform finishing touches to 1 UI 45 NA Playlist Management 2 NA Synchronized Playlist 3 NA Remote Spin 4 Project Scope, Project Vision and Product Features The Creative Spin System works with the iPod application on the iPhone to allow the user to create and modify playlists from the phone as opposed to doing so through iTunes. Additionally, CreativeSpin creates modes for listening to the playback of a collection of songs, hereto referred to as a playlist. The first mode is called Radio Play. Radio Play shuffles a playlist with one important caveat. An artist may not be repeated within a certain number of songs. The number of songs is dynamic and based on the composition of the playlist. Block Play mode will take a playlist and organize it into blocks of songs. Each block represents two distinct songs from an artist. Favorites Play mode will create a playlist for artists which have three or more albums in the user's music library. Lastly, Creative Spin aims to aid users in the organization of music by release date. Folders will be generated by decades and year to year for the current decade. Scope Feature Feature Name Release FE-1 Playback Mode- Radio 1-Fully Implemented FE-2 Playback Mode- Block 1-Fully Implemented FE-3 Era Organization 1-Partially Implemented FE-4 Playlist Management 2-Canceled (See change request 1) FE-5 Synchronized Playback 3 FE-6 Remote Spin 4 Background, Business Opportunity, and Customer Needs The reasoning behind the vision: • Music is a representation of the self. Creative Spin aims to help users generate playlists that represent their favorite music. To facilitate this music is automatically organized by decade except for the current decade we are in. The current decade is broken down year by year. We want users to create playlists based on their favorite music by decade and additionally have an easy way to 46 identify new recordings that have been released recently. • The inability of the shuffle feature to prevent artists from being played repeatedly within a short interval of time is a potential frustration iPod users. • Creating interactive applications that bring a gaming aspect to them have proven effective. Creative Spin will challenge users to submit their top playlists to Creative Spin Inc. to compete against other users for recognition and prizes for overall quality of playlist. • The inability to generate playlists from the phone that act and behave like a playlist generated from iTunes is a clear frustration of iPod users. (Canceled see change request 1) The target markets include: • Anyone who uses the iPod application. The experience the listening modes create and the organization of content could be motivation enough to want to use the application. • Music power users. The ability to modify playlists from the phone is extremely beneficial to power users because they listen to playlists on the go and need the ability to capture desired changes which will be forgotten by the time they get to their machine where iTunes resides.(Canceled see change request 1) The problems which the application attempts to solve are: • Improving the shuffle listening mode • Expanding the limited set of listening modes on the player • Improving organization of content for an improved user experience • Modifying and creating genuine playlists from the phone (canceled see change request 1) Business Objectives and Success Criteria Business Objective 1: Create a buzz for the application Business Objective 2: Get sponsors from within the music industry Success Criteria 1: 10,000 downloads by year two Business Risks Risk 1:Users may not be interested in Creative Spin Risk 2:Another application beats Creative Spin to market Risk 3: Apple doesn’t authorize due to perceived threat to iPod’s image Assumptions and Dependencies Assumption 1: User is running OS3 or later 47 Stakeholder Profiles Stakeholder Major Value Attitudes Major Interest Constraints Users Generate revenue by downloading application through iTunes Love and passion for playing music on their iPhone. A desire to organize music into playlists. Organizing music on their iPhone and improved listening experience. Must be running OS3 or later. Project Team Develop and maintain Creative Spin Commitment to Develop and Schedule and product maintain a high expertise quality product on time. Fulfill a personal need. Project Priorities Dimension Driver Constraints Schedule Complete application by 04/01/2012 Features Staff Degree of Freedom All features scheduled for release 1.0 must be fully operational 1 developer Cost Free labor OVERALL DESCRIPTION Product Perspective Creative Spin is a music content application designed to work with the iPod to enhance iPod users’ music experience. There is only one class of user in that all users have the same privileges. However, we acknowledge the fact that the application will have value to two different types of users and they will be categorized as such. This distinction will help to guide the creation of the user interface so the basic user will not be inundated with features that will never be used by that user. 48 User Classification The users can be categorized into the two following categories: • Basic User: Will want to use the Radio Playback and perhaps Block Play feature when shuffling on entire library or the occasional playlist. Will benefit from the improved organization of content. • Power User: Will do everything the Basic User does but also will want to modify playlists on the fly because playlist generation is a big part of power user’s behavior. Will potentially participate in the submission of playlists for recognition and prizes. SYSTEM FEATURES Playlist Management (canceled-see change request) Playlist Management: Priority and Description Priority High Manual Playlist Creation Priority High A user can create a playlist. The playlist will be created by adding songs from artists into the playlist. This release will only support playlist generation by songs. Future releases will include the ability for users to generate playlists from artists and genres. Manual Playlist Edit Priority High A user can modify an existing playlist. Modifications will include the ability to remove a song from the playlist, copy a song to another playlist, or move the song to another playlist. Automatic Playlist Creation Priority High The Creative Spin application will generate playlists for every past decade and a playlist for every year within the current decade. Songs will then be placed in the corresponding chronologically ordered playlist accordingly. The Creative Spin application will also 49 generate a comprehensive series of playlists representing the multitude of musical genres. Each song will be placed in the corresponding musical genre appropriately. To get the year and genre Creative Spin will have to obtain this information via the Internet. Playlist Management: Stimulus and Response Manual Playlist Creation Stimulus: User selects create playlist through UI Response: The system provides a playlist creation form Stimulus: User fills out form and clicks done Response: The system adds newly created playlist to playlist table Playlist Modification through Playlist View Stimulus: User selects modify playlist through UI Response: The system provides a table of playlists to modify Stimulus: User selects playlist to modify Response: The system opens the playlist and provides a table of its songs Stimulus: User selects a song Response: The system opens song modification page with option to delete, copy, or move song. Playlist Modification through Song View Stimulus: User selects edit song from now playing page (current song being played) Response: The system opens song modification page with option to delete, copy, or move song. Automatic Playlist Generation Stimulus: Application ran for the first time Response: The system generates playlists for every past decade, every year for current decade, and for every musical genre. Stimulus: User opens playlist from decade, year, or genre Response: System has propagated every song from library into appropriate automatic playlist. Playlist Management: Functional Requirements Manual Playlist Creation Function The system shall: Playlist.Create allow user to create a playlist 50 provide a form with required playlist fields Playlist.Create.Form Playlist.Create.UpdateTable update the playlist table with the newly created playlist Manual Playlist Edit Function The system shall: Modify.Playlist Allow user to make changes to playlist through currently playing song or through directly going to a playlist Modify.Playlist.Delete Deletes song from selected playlist Modify.Playlist.Move Moves song from selected playlist to another specified playlist Modify.Playlist.Copy Copies song from selected playlist to another specified playlist Playlist Management: Automatic Playlist Creation Function The system shall: Playlist.Auto.Eras Automatically create a playlist for each decade Playlist.Auto.Eras.Propagate Pull the release date for each album and place it into the corresponding playlist Playlist.Auto.Genre Create a playlist for every genre Playlist.Auto.Genre.Propagate Pull the genre for every album and place it into the corresponding playlist Playback Modes The application should imitate the feel of an independent radio station. Songs selected from a playlist will be random except for the fact that artists will not be repeated within a playlist for a specified sequence of songs. This feature will be referred to as Radio Play. Additionally, the user can select Block Play which shuffles through a playlist but deliberately plays a block of songs from an artist before random selecting another artist to play a block of songs. Block Play will work best on large playlists such as the entire library. 51 Priority and Description Radio Play Priority High The shuffle player on the iPhone does not prevent the same artists from being played repeatedly within a playlist. For example, an artist may be played four times in a row from within a playlist. Radio playback seeks to imitate a more radio-like user experience where artist may not be played twice within a sequence of songs. The length of the sequence shall be determined by the composition of the playlist where the length of the sequence is proportional to the length of the playlist. In other words the larger the playlist the longer the length of the sequence. Block Play Priority High Block shuffle works the same as random shuffle except that instead of preventing the same artist from being played within a sequence of songs block shuffle forces the same artist to be played twice before moving to the next artist. The repeated play of the same artist is defined as a block. Stimulus/Response Sequences Radio Play Stimulus: User selects a playlist to be played Response: System displays the playlist Stimulus: User selects radio play shuffle Response: System shuffles playlist with expected behavior Block Play Stimulus: User selects a playlist to be played Response: System displays the playlist Stimulus: User selects block play shuffle Response: System shuffles playlist with expected behavior Functional Requirements Radio Play Function The system shall: Sequence.Size Create the size of the sequence based on 52 the number songs within the list. The size will be relative to the number of songs within the playlist. For example a playlist with 100 songs will have a smaller sequence than a playlist with a 1000 songs. Sequence.Size.Maximum The maximum size of any sequence shall not be greater than 25. Sequence.Format Prepares the playlist for playback. Sequence.Fill Adds artists to sequence. Sequence.Size All songs must be played within a playlist before the same song may be played twice. Block Play Function The system shall: Block.Size Block is set at size 2 Block.NoRepeat.Song All songs must be played within a playlist before the same song may be played twice. Block.NoRepeat.Artist No artists shall be repeated through an iteration of the playlist. An iteration is defined as playing a block from every artist who has a block in the playlist. Block.Randomize The order in which artist are played through each iteration should be randomized. Block.Format Prepares the playlist for playback. Block.Sequence.Fill Adds artists to sequence. Block.Sequence.Size The size of the sequence is proportional to the number of artists in the sequence. User Interface User Interface: Priority and Description To be an effective iPhone application it must possess a stellar user interface. Fortunately for iPhone developers Apple has provided the UIKit framework which provides all the classes necessary to create advanced user interfaces either through direct use of the class or through inheritance. Creative Spin will be built predominantly from TabViews, 53 NavigationViews, and TableViews. Priority High User Interface: TabView Priority High TabViews provide a mechanism for allowing the user to choose from several views. The TabView will be the framework for user interface. From the home page the user will be able to choose between three primary views from the tab: PlaylistView, ErasView, and LibraryView. The default view will be the PlaylistView. Favorites View and Genre View will be slated for Release 2. User Interface: NavigationView Priority High NavigationViews provide a hierarchical structure to viewing the application. The three primary views of the application provided by the TabView will be NavigationViews. Each view then will have a “drill down” mechanism allowing for the user to have a logically organized way to arrive at the “final view”. User Interface: TableView Priority High TableViews provide a mechanism for displaying the “drill down” options within the NavigationViews. Each of the three NavigationViews will use a TableView within the NavigationView. User Interface: Stimulus/Response Sequences User Interface: TabView Stimulus: User starts application Response: System displays default PlaylistView from TabView. Eras View and Library View are available for selection from TabView. User Interface: NavigationView Stimulus: User selects a NavigationView from the TabView menu Response: The system provides the NavigationView with a TableView for “drill down” 54 selection. Stimulus: The user selects a row from the TableView within the NavigationView Response: The system responds to the action associated with that row within the table. User Interface: TableView Stimulus: User selects a row from the TableView Response: System performs action associated with that row within the table. User Interface: Functional Requirements TabView Functional Requirements Function The system shall: TabView.load Loads the TabView onto the Window TabView.unload Unloads the TabView from the Window NavigationView Functional Requirements Function The system shall: NavigationView.load Loads the selected NavigationView from the TabView menu onto the View hierarchy NavigationView.unload Unloads the NavigationView from the view hierarchy TableView Functional Requirements Function The system shall: TableView.select Triggers the action associated with selecting a row from a TableView Eras Organization Priority and Description Priority Medium To help the user classify their music library their will be a TabView option called ErasView. This view will be a NavigationView that presents the user with Playlists of the albums within their music library by decade. The decades will start at 50’s and earlier and then go from there: 60’s, 70’s, 80’s, 90’s, 00’s, and 10’s. Additionally, there will be 55 three more playlists: Last 5 years, last 2 years, and current year. This structure will help to create playlist that represent eras of time. Additionally, the playlists that represent new music will help the user to stay on top of the new music within his/her library. These last three playlists are aimed at the power user who is constantly buying new music. This will help the user to identify the new music within their library for easy listening. Additionally, this is different than iPod’s Recently Added playlist in that recently purchased music that is not new, defined as released more than 5 calendar years ago, does not reside within any of the three aforementioned playlists. Stimulus/Response Sequences Playlist Selected Stimulus: User clicks on ErasView in TabView menu Response: System provides displays ErasView NavigationView Stimulus: User selects a playlist from TableView within ErasView Response: System displays songs from the decade selected. Stimulus: User selects playback mode Response: System plays back decade in selected mode. Edit (Canceled) Stimulus: User clicks ErasView in TabView Response: System provides display of ErasView NavigationView Stimulus: User selects a playlist from TableView within ErasView Response: System displays songs within the playlists in alphabetical order sorted by album. Stimulus: User clicks edit Response: System displays edit view for the selected playlist Stimulus: User clicks delete Response: System deletes album from playlist Functional Requirements Initial release will only create the user interface for this module. Function The system shall: Eras.GeneratePlaylists Create a playlist for every decade and three playlist to hold albums from the last five years, last two years, and current year. The current year is treated as a full year regardless of where we are in the calendar year. For example if it is June 10th of 2010, the last two years is defined as all albums released in 2009 and all albums released in 2010. Therefore last two years and last 56 five years will always technically be less than two and five years unless it is December 31st of the current year. Eras.SelectPlaylist The playlist selected is displayed to the user by release date of the song. Synchronized Playback (not implemented) Synchronized Playback: Priority and Description Priority Low Synchronized playback is the ability for two users to listen to the same playlist on two individual phones. One user synchs up with the other user and they both listen to the same playlist. This feature is targeted at people who share the same musical passions and participate in activities together. A seminal example of this would be two individuals snowboarding together while listening to the same playlist. Stimulus/Response Sequences Stimulus: User clicks synch playlist with user Response: The system displays the set of playlists to choose for synchronization Stimulus: The user selects the playlist to synch Response: The playlist is displayed Stimulus: User selects synch with user Response:The system brings up a list of users to synch with. Stimulus: The user selects a target user to synch with Response: The system sends a notification to the user asking for permission to synch Stimulus: Targeted user accepts invitation Response: The system synchs the two phones together for shared listening. Response: Both user and targeted user are notified synchronization has completed Stimulus: User presses play Response: Shared listening experience begins Functional Requirements (Release 3) Remote Spin Priority and Description Priority Low( Release 3) Remote spin will allow a user to select songs remotely to be played on another person’s iPhone. For example if a friend is driving on a trip you could select songs for him to 57 listen to in real time as he is driving or select songs to spin at a party remotely. Functional Requirements (future release) USE CASES AND MODULES Use Case 1 Name: Radio Play Mode Description: Radio Play is selected on a playlist Actor: User Basic Flow: 1. User: selects playlist from Playlists view 2. System: presents songs from playlist along with playlist modes 3. User: selects Radio Play mode 4. System: formats the playlist for playback 5. System: starts playback of playlist 6. System: displays song information for the current song 7. System:playback continues without repeating artists Alternative Flow: 1. User: selects Library view 2. System presents all songs from Library 3. System presents Radio Play and Block Play modes. 4. User: selects Radio Play mode 5. System: formats the playlist for playback 6. System: displays song information for the current song 7. System:playback continues without repeating artists Alternative Flow: 1. User: selects Eras view 2. System: presents playlist for each decade user has songs from. 3. User: selects a decade 4. System: presents songs from that decade 5. System: presents Radio and Block modes 6. User: selects Radio mode 7. System: formats the playlist for playback 8. System: starts playback of list 9. System: displays song information for 58 the current song 10. System: playback continues without repeating artists. Use Case 2 Name: Block Play Mode Description: Block Play is selected on a playlist Actor: User Basic Flow: 1. User: selects playlist from Playlists view 2. System: presents songs from playlist along with playlist modes 3. User: selects Block Play mode 4. System: formats the playlist for playback 5. System: starts playback of playlist 6. System: displays song information for the current song 7. System:playback continues repeating artists in blocks Alternative Flow: 1. User: selects Library view 2. System presents all songs from Library 3. System presents Radio Play and Block Play modes. 4. User: selects Block Play mode 5. System: formats the playlist for playback 6. System: displays song information for the current song 7. System:playback continues repeating artists in blocks Alternative Flow: 1. User: selects Eras view 2. System: presents playlist for each decade user has songs from. 3. User: selects a decade 4. System: presents songs from that decade 5. System: presents Radio and Block modes 6. User: selects Block mode 7. System: formats the playlist for playback 8. System: starts playback of list 9. System: displays song current song 10. System: playback continues repeating artists in blocks 59 Use Case 3 Name: Switches Playlist Description: User goes from playing one playlist to another. Actor: User Precondition: User is listening to a playlist and is viewing the song information. Basic Flow: 1. User: returns to the view that displays all the songs in the current playlist 2. System: presents songs from playlist along with playlist modes 3. User: selects to return to the display that displays all the playlists 4. System: displays all the playlists 5. User: selects a different playlist than the current playlist playing 6. System: displays songs and modes for the playlist. 7. User selects mode 9. System: formats new playlist 10. System: stops playback of song from old playlist 10. System: begins playback of new playlist 11 . System: song information for current song is displayed Use Case 4 Name: Switches Modes Description: User switches mode on a playlist Actor: User Precondition: User is listening to a playlist and is viewing the song information. Basic Flow: 1. User: returns to the view that displays all the songs in the current playlist 2. System: presents songs from playlist 60 along with playlist modes 3. User: selects a different mode 4. System: reformats the current playlist 5. System: stops the current song and begins playback of playlist in new mode 6. System: the sequence is reset to new mode 7. System: song information for current song is displayed Modules Modules Functionality Requirements/Constraints TabularController Organizes the data into distinct views 1. Presents the Playlists, Eras, and Library Views 2. Load time should be no more than 5 seconds. PlaylistController View for displaying existing 1. All playlists must be playlist in the users iPhone. displayed. 2. Selection of playlist in view loads that playlist 3. Allows for access to song when playback is occurring 4. Provides mechanism to switch to another playlist while one is currently playing. 5. View should load in no more than 2 seconds. IndividualPlaylistController View for displaying songs in 1. Displays all songs in a a playlist. playlist. 2. Provides playback modes. 3. Allows for access to song when playback is occurring. 4. Provides mechanism to begin playback of a playlist. 5. View should load in no more than 2 seconds. LibraryViewController Retrieves all songs in the library 61 1. Displays all songs in library 2. Provides playback modes. 3. Allows for access to song when playback is occurring. 4. Provides mechanism to begin playback. 5. View should load in no more than 4 seconds. ErasViewController Organizes songs in library by decade SongViewController Displays meta data for song 1. Displays song title 2. Displays artist of song 3. Displays album of song 4. Displays a counter which presents time since playback of song started. 5. Displays a counter which presents time until song finishes. 6. Provides a mechanism for skipping a song. 7. Provides a mechanism for going back to the previous song. 8. Provides a mechanism for pausing a song. 9. Provides a mechanism for restarting a song. 10. Provides a mechanism for returning to the view of the collection of songs for which the song belongs. Radio Play Prevents an artist from being repeated during playback for a dynamically determined number of 62 1. Songs are grouped into playlist for each decade going back to the 1950's. 2. All songs prior to 1950's will be merged into one decade. 3. Allows for access to song when playback is occurring. 4. View should load in no more than 4 seconds. 1. An artist may not have a song played if that artist has had a song played within N number of songs. Block Play songs. 2. The length of N must be proportional to the number of songs in the playlist, i.e. as the number of songs in the playlist goes up so does N. 3. The length of N must be less than the number of artist in the playlist. 4. Transitioning from one song to the next must not take more than five seconds. 5. Formatting the list must not take more than 5 seconds. 6. The modes should be able to be selected from within the application from any collection of songs that may be played back. Guarantees that two songs from an artist will be played consecutively throughout playback. 1. At the start of playback an artist shall not be played if the artist has less than two songs in the playlist. 2. During each pass through the playlist an artist shall not be played if the number of songs remaining for the artist is less than two. 3. An attempt should be made so that the artists are played in a different order through each pass through the playlist. NON_FUNCTIONAL REQUIREMENTS Performance • • The load time for start up should be no more than five seconds. The load time for the Playlists navigation view should be no more than two 63 • • • • • • seconds. The load time for the Eras navigation view should be no more than two seconds. The load time for the Library navigation view should be no more than three seconds. The load time for the Individual Playlist view should be no more than two seconds. The time to begin playback of a song for Radio Play mode should be no more than two seconds. The time to begin playback of a song for Block Play mode should be no more than five seconds. Application must save state before termination. Security • The user expects that the application will not alter their music library any way. Usability • According to the guidelines set forth by Apple best practices the UI should be constructed of UI components and controllers provided by the SDK. • According to the guidelines set forth by Apple's best practices the customization of the UI should be performed through the use of Delegation objects. • A user must be able to select a playlist playback mode from within the application • Application must save state before termination. • A user must be able to navigate to other views while listening to a playlist without affecting the current playback of that list. • An existing iPod user should be able perform the playback of a playlist within 120% of the time required to playback a playlist on the iPod by the third attempt. Scalability • The application must meet the performance requirements on phones with 64GB of storage. Maintainability • The design of the application should allow for the adding of new modes without requiring major refactoring of the code base. Any time spent outside the implementation of the new mode should take less than two weeks of development time and two weeks of verification time. 64 TRADE STUDY Due to the nature of the project a legitimate trade study was not performed. Informal conversations were made with friends, family, and other students to determine the need or lack thereof for the features proposed by this project. The determination was made based on these informal conversations that the functionality proposed in this project would be well received. If a commercial version of the application were to be produced, research would be required to make a more formal decision as to the viability of the product. CHANGE REQUEST 1 On June 24th, 2010 Apple released the iPhone 4s. This release introduced the editing of playlist on the phone. As a result Playlist Management under heading 3.1 will be canceled from the project. It was an encouraging sign that Apple also deemed the feature to a worth while inclusion into the their latest iPod player. Despite this the intention of the project is to not compete directly with the iPod player and so the feature is being dropped. It should be noted however that Apple's version of playlist editing is different than the feature that was to be a part of Creative Spin. Apple's feature treats the listening and editing of playlist to be independent actions whereas the feature in Creative Spin would have treated them as a chained event. In other words editing of a playlist will occur as a result of listening to the playlist. 65 APPENDIX B: STATISTICAL ANALYSIS Purpose Determine if the shuffle feature on a first generation iPhone 3G follows a randomized distribution. Composition of Playlist Analyzed Number of Artists: 102 Number of Songs: 364 Technique Playback of the playlist was performed in fifteen distinct sessions. Each session consisted of twenty songs played back. Each time a song was played the artist of the song was recorded. With a total of fifteen playback sessions with twenty songs per playback the total number of songs played was three hundred. Based on the proportion of songs each artist contained within the playlist an expectation was calculated for the number of plays each artist would be expected to have. The difference between the expected number of plays and the actual number of plays was then determined. The linear correlation coefficient was calculated to show the relationship between the expected number of plays and the actual number of plays. Results Correlation Function: .923 Conclusion This analysis strongly suggests that the shuffle feature is randomized. Data Artist Name Airborne Alejandro Escovedo American Rejects Trail of Dead Animal Collective Antlers Arcade Fire Number of Songs Proportion Expected Plays Actual Plays 3 2 1 6 4 4 19 66 0.82% 2.4725274725 0.55% 1.6483516484 0.27% 0.8241758242 1.65% 4.9450549451 1.10% 3.2967032967 1.10% 3.2967032967 5.22% 15.6593406593 3 0 2 1 4 3 14 Artist Name Aska Atlas Sound Beach House Beck Best Coast Big Pink Big Spider’s Back Birds and Batteries Black Kids Block Party Blondie Blur Boards of Canada Brazos Broken Bells Broken Social Scene Kevin Drew Built to Spill Camera Obscura Casper Bangs Cold War Kids Crooked Fingers Death Cab Dirty Projectors Dntel Feat Ben G. The Dodos Edward Sharpe Elvis Costello Erich Bachman Flaming Lips Frightened Rabbit Girls Grizzly Bear Helio Sequence Hooray For Earth Islands Janka Nabay Japandroids Number of Songs Proportion Expected Plays Actual Plays 1 5 1 3 1 1 1 1 5 3 2 1 1 1 2 7 2 11 1 1 1 1 13 1 1 1 1 3 1 5 4 1 3 6 1 1 1 4 67 0.27% 0.8241758242 1.37% 4.1208791209 0.27% 0.8241758242 0.82% 2.4725274725 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 1.37% 4.1208791209 0.82% 2.4725274725 0.55% 1.6483516484 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 0.55% 1.6483516484 1.92% 5.7692307692 0.55% 1.6483516484 3.02% 9.0659340659 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 3.57% 10.7142857143 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 0.82% 2.4725274725 0.27% 0.8241758242 1.37% 4.1208791209 1.10% 3.2967032967 0.27% 0.8241758242 0.82% 2.4725274725 1.65% 4.9450549451 0.27% 0.8241758242 0.27% 0.8241758242 0.27% 0.8241758242 1.10% 3.2967032967 2 2 0 2 0 2 0 0 4 5 0 0 0 0 6 4 1 10 0 1 0 0 11 0 1 0 1 2 1 2 5 0 2 3 0 1 2 0 Artist Name JBM Jesus Mary Chain Jookabox Julian Casablancas Kings of Leon Kurt Vile Les Savy Fav Little Girls Little Jackie Local Natives Loch Lomond M Ward Maps Metric MGMT Miike Snow Modest Mouse My Chemical Romance Nada Surf Nancy Sinatra Neon Indian Nirvana No Age PaperCuts Passion Pit Pastels and Tenniscoats Pavement Penguin Prison Phantogram Phoenix Pixies Postal Service Radiohead RealEstate Santogold Sebadoh Shins Silversun Pickups Number of Songs Proportion Expected Plays Actual Plays 1 3 1 1 5 1 6 1 1 2 1 1 1 4 5 4 20 4 1 1 1 2 1 1 1 1 5 1 4 22 7 3 20 1 3 1 3 13 68 0.27% 0.82% 0.27% 0.27% 1.37% 0.27% 1.65% 0.27% 0.27% 0.55% 0.27% 0.27% 0.27% 1.10% 1.37% 1.10% 5.49% 1.10% 0.27% 0.27% 0.27% 0.55% 0.27% 0.27% 0.27% 0.27% 1.37% 0.27% 1.10% 6.04% 1.92% 0.82% 5.49% 0.27% 0.82% 0.27% 0.82% 3.57% 0.8241758242 2.4725274725 0.8241758242 0.8241758242 4.1208791209 0.8241758242 4.9450549451 0.8241758242 0.8241758242 1.6483516484 0.8241758242 0.8241758242 0.8241758242 3.2967032967 4.1208791209 3.2967032967 16.4835164835 3.2967032967 0.8241758242 0.8241758242 0.8241758242 1.6483516484 0.8241758242 0.8241758242 0.8241758242 0.8241758242 4.1208791209 0.8241758242 3.2967032967 18.1318681319 5.7692307692 2.4725274725 16.4835164835 0.8241758242 2.4725274725 0.8241758242 2.4725274725 10.7142857143 1 2 2 3 6 1 7 0 0 2 0 0 0 1 6 2 18 4 0 2 1 0 1 1 2 1 7 0 3 16 8 2 20 2 3 0 3 15 Artist Name Smashing Pumpkins Spoon Stills Strokes Talking Heads Tanlines Tapes n Tapes Tv on the Radio The Very Best Violent Femmes Virgins Washed Out Weezer White Sea Wilco Wild Beasts The XX Yeah Yeah Yeahs Total # Songs Number of Songs Proportion Expected Plays Actual Plays 1 13 2 3 1 1 3 2 1 2 5 1 6 4 4 6 7 5 0.27% 0.8241758242 3.57% 10.7142857143 0.55% 1.6483516484 0.82% 2.4725274725 0.27% 0.8241758242 0.27% 0.8241758242 0.82% 2.4725274725 0.55% 1.6483516484 0.27% 0.8241758242 0.55% 1.6483516484 1.37% 4.1208791209 0.27% 0.8241758242 1.65% 4.9450549451 1.10% 3.2967032967 1.10% 3.2967032967 1.65% 4.9450549451 1.92% 5.7692307692 1.37% 4.1208791209 1 14 2 4 2 2 1 0 0 1 2 1 2 2 6 3 6 8 364 300 300 69
© Copyright 2024