├── CanvasKitTests ├── Fixtures │ ├── model_string.json │ ├── oauth_user_data.json │ ├── favorite.json │ ├── rubric_criterion_rating.json │ ├── rubric.json │ ├── outcome_link.json │ ├── poll_choice.json │ ├── poll_submission.json │ ├── service.json │ ├── term.json │ ├── tab.json │ ├── live_assessment.json │ ├── media_comment.json │ ├── poll.json │ ├── section.json │ ├── account.json │ ├── poll_session.json │ ├── outcome.json │ ├── submission_comment.json │ ├── group.json │ ├── user.json │ ├── users_array.json │ ├── activity_stream_item.json │ ├── activity_stream_conference_item.json │ ├── activity_stream_collaboration_item.json │ ├── outcome_group.json │ ├── activity_stream_submission_item.json │ ├── activity_stream_message_item.json │ ├── activity_stream_conversation_item.json │ ├── rubric_criterion.json │ ├── activity_stream_announcement_item.json │ ├── external_tool.json │ ├── folder.json │ ├── activity_stream_discussion_topic_item.json │ ├── page.json │ ├── module_item.json │ ├── file.json │ ├── calendar_event.json │ ├── quiz.json │ ├── course.json │ ├── todo_item.json │ └── enrollment.json ├── CanvasKitTests-Bridging-Header.h ├── Helpers.h ├── Model Tests │ ├── CKIISO8601DateMatcher.h │ ├── CKIFavoriteTests.swift │ ├── CKIActivityStreamMessageItemTests.swift │ ├── CKIActivityStreamConferenceItemTests.swift │ ├── CKIActivityStreamCollaborationItemTests.swift │ ├── CKIActivityStreamAnnouncementItemTests.swift │ ├── CKIRubricTests.swift │ ├── CKIISO8601DateMatcher.m │ ├── CKIServiceTests.swift │ ├── CKIActivityStreamConversationItemTests.swift │ ├── CKISectionTests.swift │ ├── CKITermTests.swift │ ├── CKIActivityStreamSubmissionItemTests.swift │ └── CKILiveAssessmentTests.swift ├── Networking │ ├── CKIClient+TestingClient.h │ ├── CKIModel+NetworkingSpec.m │ ├── CKIClient+CKIFileSpec.m │ ├── CKIClient+CKIServiceSpec.m │ └── CKIClient+CKICourseSpec.m ├── CanvasKitTests-Info.plist ├── Info.plist ├── Helpers.m ├── attachment.json ├── Networking Tests │ ├── CKILiveAssessmentNetworkingTests.swift │ ├── CKIServiceNetworkingTests.swift │ ├── CKITabNetworkingTests.swift │ ├── CKIAssignmentNetworkingTests.swift │ ├── CKIOutcomeNetworkingTests.swift │ ├── CKIAssignmentGroupNetworkingTests.swift │ ├── CKIOutcomeLinkNetworkingTests.swift │ └── CKITodoItemNetworkingTests.swift ├── ___ZZZ999CodeCoverageDump.m ├── Helpers.swift └── Models │ ├── CKIClient+CKIModelSpec.m │ ├── CKIActivityStreamMessageItemSpec.m │ ├── CKIActivityStreamConversationItemSpec.m │ ├── CKIServiceSpec.m │ └── CKIActivityStreamDiscussionTopicItemSpec.m ├── Example ├── CanvasKit 2.0 Example │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── utah.jpg │ ├── CKAppDelegate.h │ ├── main.m │ ├── CanvasKit 2.0 Example-Prefix.pch │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── CKCoursesTableViewController.h │ ├── CKAssignmentsTableViewController.h │ ├── CKViewController.h │ ├── CKCourseDetailsTableViewController.h │ ├── CKTodoItemsTableViewController.h │ ├── CKUserDetailsViewController.h │ ├── CKAssignmentsTableViewController.m │ └── CanvasKit 2.0 Example-Info.plist ├── CanvasKit 2.0 ExampleTests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── CKLoginTests.m │ └── CanvasKit 2.0 ExampleTests-Info.plist └── Podfile ├── Cartfile ├── Cartfile.resolved ├── CanvasKit.xcodeproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── CanvasKit ├── Networking │ ├── CKIClient+Login.h │ ├── CKIClient+Login.m │ ├── CKIClient+CKIAccountDomain.h │ ├── CKIClient+CKIService.h │ ├── Live Assessments │ │ ├── CKIClient+CKILiveAssessment.h │ │ ├── CKIClient+CKILiveAssessmentResult.h │ │ └── CKIClient+CKILiveAssessmentResult.m │ ├── CKIClient+CKIModel.h │ ├── CKIClient+CKIOutcome.h │ ├── CKIClient+CKIOutcomeLink.h │ ├── CKIClient+CKITab.h │ ├── CKIClient+CKIConversationRecipient.h │ ├── CKIClient+CKISection.h │ ├── CKIClient+CKITodoItem.h │ ├── CKIClient+CKIQuiz.h │ ├── CKIClient+CKIGroupCategory.h │ ├── CKIClient+CKIPoll.h │ ├── CKIClient+CKIFavorite.h │ ├── CKIClient+CKIPollSubmission.h │ ├── CKIClient+CKIFile.h │ ├── CKIClient+CKIPage.h │ ├── CKIClient+CKIPollChoice.h │ ├── CKIClient+CKICourse.h │ ├── CKIClient+CKIOutcomeGroup.h │ ├── CKIClient+CKIAccountDomain.m │ ├── CKIClient+CKIService.m │ ├── CKIClient+CKIAssignment.h │ ├── CKIClient+CKIDiscussionTopic.h │ ├── CKIClient+CKIModuleItem.h │ ├── CKIMediaServer.h │ ├── CKIClient+CKIOutcome.m │ ├── CKIClient+CKITab.m │ ├── CKIClient+CKIPollSubmission.m │ ├── CKIClient+CKISubmissionRecord.h │ ├── CKIClient+CKIActivityStreamItem.h │ ├── CKIClient+CKIExternalTool.h │ ├── CKIClient+CKISubmissionComment.h │ ├── CKIClient+CKIModel.m │ ├── CKIClient+CKISection.m │ ├── CKIClient+CKIPollSession.h │ ├── CKIClient+CKIQuiz.m │ ├── CKIClient+CKIAssignmentGroup.h │ ├── CKIClient+CKIModule.m │ ├── CKIClient+CKIModule.h │ ├── CKIClient+CKIActivityStreamItem.m │ ├── CKIClient+CKIOutcomeLink.m │ ├── CKIClient+CKICalendarEvent.h │ ├── CKIClient+CKIGroupCategory.m │ ├── CKIClient+CKIUser.h │ ├── CKIClient+CKIPage.m │ ├── CKIClient+CKIConversationRecipient.m │ ├── CKIClient+CKIGroup.h │ ├── CKIClient+CKITodoItem.m │ ├── CKIClient+CKIPollChoice.m │ ├── CKIClient+CKIPoll.m │ └── CKIClient+CKIExternalTool.m ├── Models │ ├── CKIAPIV1.h │ ├── CKISection.h │ ├── CKITerm.h │ ├── CKIPoll.h │ ├── CKISubmissions │ │ ├── CKISubmission+TextEntrySubmissionHTMLFile.h │ │ ├── CKISubmission+DiscussionSubmissionHTMLFile.h │ │ ├── DiscussionSubmissionHTML │ │ │ └── discussion_submissions.css │ │ ├── CKISubmissionComment.h │ │ ├── CKISubmissionRecord.h │ │ ├── CKIMediaComment.h │ │ ├── CKIMediaComment.m │ │ └── CKISubmissionComment.m │ ├── CKIRubricAssessment.h │ ├── CKIPollSubmission.h │ ├── CKIActivityStreamConferenceItem.h │ ├── CKITab.h │ ├── Live Assessments │ │ ├── CKILiveAssessment.h │ │ ├── CKILiveAssessmentResult.h │ │ ├── CKILiveAssessment.m │ │ └── CKILiveAssessmentResult.m │ ├── CKIPollChoice.h │ ├── CKIActivityStreamCollaborationItem.h │ ├── CKIActivityStreamAnnouncementItem.h │ ├── CKIAccountDomain.h │ ├── CKIService.h │ ├── CKIFavorite.h │ ├── CKIActivityStreamSubmissionItem.h │ ├── Rubric │ │ ├── CKIRubric.m │ │ ├── CKIRubricCriterionRating.m │ │ ├── CKIRubric.h │ │ ├── CKIRubricCriterionRating.h │ │ └── CKIRubricCriterion.h │ ├── CKIAPIV1.m │ ├── CKIActivityStreamConversationItem.h │ ├── CKIContext.h │ ├── CKIPollSession.h │ ├── CKITodoItem.h │ ├── CKILockableModel.h │ ├── CKILockableModel.m │ ├── CKIAttachment.h │ ├── CKIAssignmentGroup.h │ ├── CKIActivityStreamDiscussionTopicItem.h │ ├── CKIActivityStreamAnnouncementItem.m │ ├── CKIActivityStreamMessageItem.h │ ├── CKIFavorite.m │ ├── CKIActivityStreamMessageItem.m │ ├── CKIAssignmentGroup.m │ ├── CKIActivityStreamConferenceItem.m │ ├── CKIOutcomeLink.h │ ├── CKIActivityStreamCollaborationItem.m │ ├── CKIActivityStreamConversationItem.m │ ├── CKIPage.h │ ├── CKITerm.m │ ├── CKISection.m │ ├── CKIActivityStreamDiscussionTopicItem.m │ ├── CKIGroupCategory.m │ ├── CKIPoll.m │ ├── CKIPollChoice.m │ ├── CKIActivityStreamSubmissionItem.m │ ├── CKIOutcome.h │ ├── CKIService.m │ ├── CKITab.m │ ├── CKIOutcome.m │ ├── CKIEnrollment.h │ ├── CKIConversationMessage.h │ ├── CKIRubricAssessment.m │ ├── CKIOutcomeGroup.h │ ├── CKIOutcomeGroup.m │ └── CKIModel.h ├── Helpers │ ├── NSString+CKIAdditions.h │ ├── NSArray+CKIAdditions.h │ ├── NSDictionary+DictionaryByAddingObjectsFromDictionary.h │ ├── CKIMediaFileUploadTokenParser.h │ ├── NSHTTPURLResponse+Pagination.h │ ├── NSDictionary+DictionaryByAddingObjectsFromDictionary.m │ ├── NSArray+CKIAdditions.m │ ├── NSString+CKIAdditions.m │ └── NSValueTransformer+CKIPredefinedTransformerAdditions.h ├── Constants.h ├── UIKit+CanvasKit │ └── CKILoginViewController.h └── Info.plist ├── .gitignore ├── CanvasKit.xcworkspace └── contents.xcworkspacedata └── LICENSE.md /CanvasKitTests/Fixtures/model_string.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "string_id" 3 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/oauth_user_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Sheldon Cooper", 4 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/favorite.json: -------------------------------------------------------------------------------- 1 | { 2 | "context_id": 1170, 3 | "context_type": "Course" 4 | } -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 ExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/utah.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instructure/CanvasKit/HEAD/Example/CanvasKit 2.0 Example/utah.jpg -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/rubric_criterion_rating.json: -------------------------------------------------------------------------------- 1 | { 2 | "points": 9.5, 3 | "id": "rat1", 4 | "description": "Full marks" 5 | } -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "Mantle/Mantle" == 1.5.5 2 | github "ReactiveCocoa/ReactiveCocoa" ~> 4.2.2 3 | github "AFNetworking/AFNetworking" ~> 3.0.0 4 | 5 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/rubric.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Made Up Title", 3 | "points_possible": 10.5, 4 | "free_form_criterion_comments": false 5 | } -------------------------------------------------------------------------------- /CanvasKitTests/CanvasKitTests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/outcome_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "/api/v1/account/1/outcome_groups/1/outcomes/1", 3 | "context_id": 1, 4 | "context_type": "Account" 5 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/poll_choice.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1023, 3 | "poll_id": 1779, 4 | "is_correct": true, 5 | "text": "Choice A", 6 | "position": 1 7 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/poll_submission.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1023, 3 | "poll_choice_id": 155, 4 | "user_id": 4555, 5 | "created_at": "2013-11-07T13:16:18Z" 6 | } -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "AFNetworking/AFNetworking" "3.1.0" 2 | github "Mantle/Mantle" "1.5.5" 3 | github "antitypical/Result" "2.1.3" 4 | github "ReactiveCocoa/ReactiveCocoa" "v4.2.2" 5 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '7.0' 2 | 3 | pod 'CanvasKit', :path => '../CanvasKit.podspec' 4 | pod 'ReactiveCocoa' 5 | 6 | 7 | target 'CanvasKit 2.0 ExampleTests' do 8 | pod 'KIF', '~> 2.0' 9 | end -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "domain": "kaltura.example.com", 3 | "enabled": true, 4 | "partner_id": "123456", 5 | "resource_domain": "cdn.kaltura.example.com", 6 | "rtmp_domain": "rtmp.example.com" 7 | } -------------------------------------------------------------------------------- /CanvasKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CanvasKitTests/Helpers.h: -------------------------------------------------------------------------------- 1 | // 2 | // XCTestCase+Helpers.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/22/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | id loadJSONFixture(NSString *fixtureName); -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/term.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "sis_term_id": "Sp2014", 4 | "name": "Spring 2014", 5 | "start_at": "2014-01-06T08:00:00-05:00", 6 | "end_at": "2014-05-16T05:00:00-04:00", 7 | "workflow_state": "active" 8 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/tab.json: -------------------------------------------------------------------------------- 1 | { 2 | "html_url": "/courses/1/external_tools/4", 3 | "url": "https://canvas.instructure.com/courses/1/external_tools/4", 4 | "id": "context_external_tool_4", 5 | "label": "WordPress", 6 | "type": "external" 7 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+Login.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+Login.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @interface CKIClient (Login) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/live_assessment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "42", 3 | "passed": "true", 4 | "assessed_at": "2014-05-13T00:01:57-06:00", 5 | "links": { 6 | "user": "42", 7 | "assessor": "23", 8 | "assessment": "5", 9 | "outcome": "10" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/media_comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "content-type" : "video/mp4", 3 | "display_name" : null, 4 | "media_id" : "0_1175s92f", 5 | "media_type" : "video", 6 | "url" : "https://mobiledev.instructure.com/users/4301217/media_download?entryId=0_1175s92f&redirect=1&type=mp4" 7 | } 8 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/poll.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1023, 3 | "question": "What do you consider most important to your learning in this course?", 4 | "description": "This poll is to determine what priorities the students in the course have.", 5 | "created_at": "2014-01-07T15:16:18Z", 6 | "user_id": 105 7 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/section.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Section A", 4 | "sis_section_id": "s34643", 5 | "integration_id": "3452342345", 6 | "sis_import_id": 47, 7 | "course_id": 7, 8 | "sis_course_id": 7, 9 | "start_at": "2012-06-01T00:00:00-06:00", 10 | "end_at": "" 11 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+Login.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+Login.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | 10 | 11 | #import "CKIClient+Login.h" 12 | 13 | @implementation CKIClient (Login) 14 | 15 | 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | 19 | #CocoaPods 20 | Pods 21 | *.xccheckout 22 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIAccountDomain.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Brandon Pluim on 3/3/15. 3 | // Copyright (c) 2015 Instructure. All rights reserved. 4 | // 5 | 6 | #import 7 | #import "CKIClient.h" 8 | 9 | @interface CKIClient (CKIAccountDomain) 10 | 11 | + (RACSignal *)fetchAccountDomains; 12 | 13 | @end -------------------------------------------------------------------------------- /CanvasKit/Models/CKIAPIV1.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIAPIV1.h 3 | // CanvasKit 4 | // 5 | // Created by derrick on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIContext.h" 11 | 12 | @interface CKIAPIV1 : NSObject 13 | + (instancetype)context; 14 | @end 15 | -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSString+CKIAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+CKIAdditions.h 3 | // OAuthTesting 4 | // 5 | // Created by rroberts on 8/23/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (CKIAdditions) 12 | 13 | - (NSDictionary *)queryParameters; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIISO8601DateMatcher.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIISO8601DateMatcher.h 3 | // CanvasKit 4 | // 5 | // Created by Miles Wright on 10/2/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "KWMatcher.h" 10 | 11 | @interface CKIISO8601DateMatcher : KWMatcher 12 | 13 | - (void)equalISO8601String:(id)anObject; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/account.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 170000000000002, 4 | "name": "Site Admin", 5 | "parent_account_id": null, 6 | "root_account_id": null, 7 | "workflow_state": "active", 8 | "default_storage_quota_mb": 500, 9 | "default_user_storage_quota_mb": 50, 10 | "default_group_storage_quota_mb": 50, 11 | "default_time_zone": "America/Denver" 12 | } 13 | ] -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSArray+CKIAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+CKIAdditions.h 3 | // CanvasKit 4 | // 5 | // Created by Ben Kraus on 12/2/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSArray (CKIAdditions) 12 | 13 | - (NSArray *)arrayByMappingValues:(NSDictionary *)valueMapping; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISection.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKISection.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/12/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKISection : CKIModel 12 | 13 | @property (nonatomic, copy) NSString *name; 14 | 15 | @property (nonatomic, copy) NSString *courseID; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKITerm.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKITerm.h 3 | // CanvasKit 4 | // 5 | // Created by derrick on 11/21/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKITerm : CKIModel 12 | @property (nonatomic) NSString *name; 13 | @property (nonatomic) NSDate *startAt; 14 | @property (nonatomic) NSDate *endAt; 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKAppDelegate.h 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CKAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIService.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIService.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIService; 12 | @class RACSignal; 13 | 14 | @interface CKIClient (CKIService) 15 | 16 | - (RACSignal *)fetchService; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Networking/Live Assessments/CKIClient+CKILiveAssessment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKILiveAssessment.h 3 | // CanvasKit 4 | // 5 | // Created by Derrick Hathaway on 6/9/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @interface CKIClient (CKILiveAssessment) 12 | - (RACSignal *)createLiveAssessments:(NSArray *)assessments; 13 | @end 14 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/poll_session.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1023, 3 | "poll_id": 55, 4 | "course_id": 1111, 5 | "course_section_id": 444, 6 | "is_published": true, 7 | "has_public_results": true, 8 | "has_submitted": true, 9 | "created_at": "2014-01-07T15:16:18Z", 10 | "results": { 11 | "144": 10, 12 | "145": 3, 13 | "146": 27, 14 | "147": 8 15 | } 16 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIModel.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIModel; 12 | 13 | @interface CKIClient (CKIModel) 14 | 15 | - (RACSignal *)refreshModel:(CKIModel *)model parameters:(NSDictionary *)params; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIOutcome.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIOutcome.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/20/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIOutcome; 12 | 13 | @interface CKIClient (CKIOutcome) 14 | 15 | - (RACSignal *)refreshOutcome:(CKIOutcome *)outcome courseID:(NSString *)courseID; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/outcome.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "url": "/api/v1/outcomes/1", 4 | "context_id": 1, 5 | "context_type": "Account", 6 | "title": "Outcome title", 7 | "display_name": "My Favorite Outocome", 8 | "description": "Outcome description", 9 | "vendor_guid": "customid9000", 10 | "points_possible": 5, 11 | "mastery_points": 3, 12 | "ratings": "", 13 | "can_edit": "true" 14 | } -------------------------------------------------------------------------------- /CanvasKit/Models/CKIPoll.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIPoll.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/7/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIPoll : CKIModel 12 | 13 | /* 14 | The title of the poll 15 | */ 16 | @property (nonatomic, copy) NSString *question; 17 | 18 | @property (nonatomic, copy) NSDate *created; 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/CKISubmission+TextEntrySubmissionHTMLFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKISubmission+TextEntrySubmissionHTMLFile.h 3 | // iCanvas 4 | // 5 | // Created by Derrick Hathaway on 9/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKISubmission.h" 10 | 11 | @interface CKISubmission (TextEntrySubmissionHTMLFile) 12 | 13 | - (NSURL *)urlForLocalTextEntryHTMLFile; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIOutcomeLink.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIOutcomeLink.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIOutcomeGroup; 12 | 13 | @interface CKIClient (CKIOutcomeLink) 14 | 15 | - (RACSignal *)fetchOutcomeLinksForOutcomeGroup:(CKIOutcomeGroup *)group; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKITab.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKITab.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKITab; 12 | @class CKICourse; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKITab) 16 | 17 | - (RACSignal *)fetchTabsForContext:(id)context; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/CKISubmission+DiscussionSubmissionHTMLFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKISubmission+DiscussionSubmission.h 3 | // iCanvas 4 | // 5 | // Created by Derrick Hathaway on 9/18/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKISubmission.h" 10 | 11 | @interface CKISubmission (DiscussionSubmissionHTMLFile) 12 | 13 | - (NSURL *)urlForLocalDiscussionEntriesHTMLFile; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIRubricAssessment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubricAssessment.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 8/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIModel.h" 11 | 12 | @interface CKIRubricAssessment : CKIModel 13 | 14 | @property (nonatomic, strong) NSArray *ratings; 15 | 16 | - (NSDictionary *)parametersDictionary; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIPollSubmission.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIPollSubmission.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIPollSubmission : CKIModel 12 | 13 | @property (nonatomic) NSString *pollChoiceID; 14 | 15 | @property (nonatomic, copy) NSString *userID; 16 | 17 | @property (nonatomic, copy) NSDate *created; 18 | 19 | @end -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIConversationRecipient.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIConversationRecipient.h 3 | // CanvasKit 4 | // 5 | // Created by Ben Kraus on 12/2/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @interface CKIClient (CKIConversationRecipient) 12 | 13 | - (RACSignal *)fetchConversationRecipientsWithSearchString:(NSString *)search inContext:(NSString *)contextID; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKISection.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKISection.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/12/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | #import "CKICourse.h" 11 | 12 | @interface CKIClient (CKISection) 13 | 14 | - (RACSignal *)fetchSectionsForCourse:(CKICourse *)course; 15 | - (RACSignal *)fetchSectionWithID:(NSString *)sectionID; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/submission_comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 37, 3 | "author_id": 134, 4 | "author_name": "Toph Beifong", 5 | "comment": "Well here's the thing...", 6 | "created_at": "2012-01-01T01:00:00Z", 7 | "media_comment": { 8 | "content-type": "audio/mp4", 9 | "display_name": "something", 10 | "media_id": "3232", 11 | "media_type": "audio", 12 | "url": "http://example.com/media_url" 13 | } 14 | } -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CKAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CKAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CanvasKit 2.0 Example-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamConferenceItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamConferenceItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamItem.h" 10 | 11 | @interface CKIActivityStreamConferenceItem : CKIActivityStreamItem 12 | 13 | /** 14 | The ID of the conference. 15 | */ 16 | @property (nonatomic, copy) NSString *conferenceID; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKITab.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKITab.h 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @class CKICourse; 12 | 13 | @interface CKITab : CKIModel 14 | 15 | @property (nonatomic) NSURL *htmlURL; 16 | 17 | @property (nonatomic) NSString *label; 18 | 19 | @property (nonatomic) NSString *type; 20 | 21 | @property (nonatomic) NSURL *url; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /CanvasKit/Models/Live Assessments/CKILiveAssessment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKILiveAssessment.h 3 | // CanvasKit 4 | // 5 | // Created by Derrick Hathaway on 6/9/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKILiveAssessment : CKIModel 12 | @property (nonatomic, copy) NSString *key; 13 | @property (nonatomic, copy) NSString *title; 14 | @property (nonatomic, copy) NSString *outcomeID; 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKITodoItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKITodoItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class RACSignal; 13 | 14 | @interface CKIClient (CKITodoItem) 15 | 16 | - (RACSignal *)fetchTodoItemsForCourse:(CKICourse *)course; 17 | 18 | - (RACSignal *)fetchTodoItemsForCurrentUser; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking/CKIClient+TestingClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+TestingClient.h 3 | // CanvasKit 4 | // 5 | // Created by derrick on 9/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @interface CKIClient (TestingClient) 12 | 13 | + (instancetype)testClient; 14 | 15 | - (void)returnErrorForPath:(NSString *)path; 16 | - (void)returnResponseObject:(id)responseObject forPath:(NSString *)path; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Constants.h: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.h 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/13/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #ifndef CanvasKit_Constants_h 10 | #define CanvasKit_Constants_h 11 | 12 | /** 13 | Error Handling Definitions 14 | */ 15 | 16 | #define kCKIErrorCodeUserCancelledOAuth 0 17 | #define kCKIErrorCodeNotPreparedForOAuth 1 18 | 19 | #define kCKIErrorDomain @"com.instructure.canvaskit" 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIPollChoice.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIPollChoice.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIPollChoice : CKIModel 12 | 13 | @property (nonatomic) BOOL isCorrect; 14 | 15 | @property (nonatomic, copy) NSString *text; 16 | 17 | @property (nonatomic) NSNumber *pollID; 18 | 19 | @property (nonatomic) NSNumber *index; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/group.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 17, 3 | "name": "Math Group 1", 4 | "description": "An awesome group about math", 5 | "is_public": true, 6 | "followed_by_user": true, 7 | "join_level": "invitation_only", 8 | "members_count": 7, 9 | "avatar_url": "https://instructure.com/files/avatar_image.png", 10 | "context_type": "Course", 11 | "course_id": 3, 12 | "role": null, 13 | "group_category_id": 4, 14 | "storage_quota_mb": 50 15 | } -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSDictionary+DictionaryByAddingObjectsFromDictionary.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+DictionaryByAddingObjectsFromDictionary.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 9/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary (DictionaryByAddingObjectsFromDictionary) 12 | - (NSDictionary *)dictionaryByAddingObjectsFromDictionary:(NSDictionary *)dictionary; 13 | @end 14 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamCollaborationItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamCollaborationItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamItem.h" 10 | 11 | @interface CKIActivityStreamCollaborationItem : CKIActivityStreamItem 12 | 13 | /** 14 | The ID of the collaboration. 15 | */ 16 | @property (nonatomic, copy) NSString *collaborationID; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Networking/Live Assessments/CKIClient+CKILiveAssessmentResult.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKILiveAssessmentResult.h 3 | // CanvasKit 4 | // 5 | // Created by Derrick Hathaway on 6/9/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKILiveAssessment; 12 | 13 | @interface CKIClient (CKILiveAssessmentResult) 14 | - (RACSignal *)createResults:(NSArray *)results forLiveAssessment:(CKILiveAssessment *)assessment; 15 | @end 16 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Sheldon Cooper", 4 | "sortable_name": "Cooper, Sheldon", 5 | "short_name": "Shelly", 6 | "sis_user_id": "scooper", 7 | "login_id": "sheldon@caltech.example.com", 8 | "avatar_url": "http://instructure.com/sheldon.png", 9 | "enrollments": [], 10 | "primary_email": "sheldon@caltech.example.com", 11 | "locale": "tlh", 12 | "last_login": "2012-05-30T17:45:25Z", 13 | "time_zone": "America/Denver" 14 | } -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /CanvasKit/Helpers/CKIMediaFileUploadTokenParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIMediaFileUploadTokenParser.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 11/25/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CKIMediaFileUploadTokenParser : NSObject 12 | 13 | - (id)initWithXMLParser:(NSXMLParser *)parser; 14 | - (void)parseWithSuccess:(void(^)(NSString *uploadID))success failure:(void(^)(NSError *error))failure; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamAnnouncementItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamAnnouncementItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamDiscussionTopicItem.h" 10 | 11 | @interface CKIActivityStreamAnnouncementItem : CKIActivityStreamDiscussionTopicItem 12 | 13 | /** 14 | The ID of the announcement. 15 | */ 16 | @property (nonatomic, copy) NSString *announcementID; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIQuiz.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIQuiz.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIQuiz; 12 | @class CKICourse; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKIQuiz) 16 | 17 | - (RACSignal *)fetchQuiz:(NSString *)quizID forCourse:(CKICourse *)course; 18 | 19 | - (RACSignal *)fetchQuizzesForCourse:(CKICourse *)course; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKCoursesTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKCoursesTableViewController.h 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CKIClient; 12 | 13 | @interface CKCoursesTableViewController : UITableViewController 14 | 15 | @property (nonatomic, strong) NSMutableArray *courses; 16 | 17 | @property (nonatomic, strong) CKIClient *client; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIAccountDomain.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Brandon Pluim on 3/3/15. 3 | // Copyright (c) 2015 Instructure. All rights reserved. 4 | // 5 | 6 | #import "CKIModel.h" 7 | 8 | 9 | @interface CKIAccountDomain : CKIModel 10 | 11 | @property (nonatomic, copy) NSString *name; 12 | @property (nonatomic, copy) NSString *domain; 13 | @property (nonatomic, strong) NSNumber *distance; 14 | 15 | + (CKIAccountDomain *)canvasNetSchool; 16 | + (CKIAccountDomain *)cantFindSchool; 17 | + (NSArray *)developmentSchools; 18 | 19 | @end -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/users_array.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 3781246, 4 | "name": "Alex", 5 | "sortable_name": "Alex", 6 | "short_name": "Alex" 7 | }, 8 | { 9 | "id": 3781254, 10 | "name": "Ale", 11 | "sortable_name": "Ale", 12 | "short_name": "A" 13 | }, 14 | { 15 | "id": 3547101, 16 | "name": "Alexander", 17 | "sortable_name": "Al", 18 | "short_name": "Al" 19 | }, 20 | { 21 | "id": 378124, 22 | "name": "Alexandria", 23 | "sortable_name": "Alexis", 24 | "short_name": "Al" 25 | } 26 | ] -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIGroupCategory.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIGroupCategory.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 12/8/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class CKIGroupCategory; 13 | 14 | @interface CKIClient (CKIGroupCategory) 15 | 16 | - (RACSignal *)fetchGroupCategoriesForCourse:(CKICourse *)course; 17 | - (RACSignal *)fetchUsersInGroupCategory:(CKIGroupCategory *)category; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKAssignmentsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKAssignmentsTableViewController.h 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CKIClient; 12 | 13 | @interface CKAssignmentsTableViewController : UITableViewController 14 | 15 | @property (nonatomic, strong) NSMutableArray *assignments; 16 | @property (nonatomic, strong) CKIClient *client; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPoll.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPoll.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/8/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | #import "CKIPoll.h" 11 | 12 | @interface CKIClient (CKIPoll) 13 | 14 | - (RACSignal *)fetchPollsForCurrentUser; 15 | 16 | - (RACSignal *)fetchPollWithID:(NSString *)pollID; 17 | 18 | - (RACSignal *)createPoll:(CKIPoll *)poll; 19 | 20 | - (RACSignal *)deletePoll:(CKIPoll *)poll; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIFavorite.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIFavorite.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class RACSignal; 13 | 14 | @interface CKIClient (CKIFavorite) 15 | 16 | - (RACSignal *)fetchFavoriteCourses; 17 | 18 | - (RACSignal *)addCourseToFavorites:(CKICourse *)course; 19 | 20 | - (RACSignal *)removeCourseFromFavorites:(CKICourse *)course; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKViewController.h 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface CKViewController : UIViewController 13 | 14 | @property (nonatomic, weak) IBOutlet UIButton *loginButton; 15 | 16 | - (IBAction)loginButtonPressed:(id)sender; 17 | 18 | @property (nonatomic, strong) CKIClient *client; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": true, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "url": "http://canvas.instructure.com/api/v1/foo", 12 | "html_url": "http://canvas.instructure.com/api/v1/foo" 13 | } -------------------------------------------------------------------------------- /CanvasKit/Models/CKIService.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIService.h 3 | // CanvasKit 4 | // 5 | // Created by Miles Wright on 10/14/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIService : CKIModel 12 | 13 | @property (nonatomic, copy) NSURL *domain; 14 | 15 | @property (nonatomic, assign) BOOL enabled; 16 | 17 | @property (nonatomic, copy) NSString *partnerID; 18 | 19 | @property (nonatomic, strong) NSURL *resourceDomain; 20 | 21 | @property (nonatomic, strong) NSURL *rtmp; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPollSubmission.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPollSubmission.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/23/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | #import "CKIPollSubmission.h" 12 | #import "CKIPoll.h" 13 | #import "CKIPollSession.h" 14 | 15 | @interface CKIClient (CKIPollSubmission) 16 | 17 | - (RACSignal *)createPollSubmission:(CKIPollSubmission *)submission forPoll:(CKIPoll *)poll pollSession:(CKIPollSession *)session; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIFavorite.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIFavorite.h 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIFavorite : CKIModel 12 | 13 | /** 14 | The ID of the object the Favorite refers to 15 | */ 16 | @property (nonatomic, strong) NSString *contextID; 17 | 18 | /** 19 | The type of the object the Favorite refers to (currently, only "Course" is supported) 20 | */ 21 | @property (nonatomic, strong) NSString *contextType; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_conference_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": false, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "html_url": "http://canvas.instructure.com/api/v1/foo", 12 | "type": "Conference", 13 | "web_conference_id": 1234 14 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_collaboration_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": false, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "html_url": "http://canvas.instructure.com/api/v1/foo", 12 | "type": "Collaboration", 13 | "collaboration_id": 1234 14 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/outcome_group.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "url": "/api/v1/accounts/1/outcome_groups/1", 4 | "parent_outcome_group": "", 5 | "context_id": 1, 6 | "context_type": "Account", 7 | "title": "Outcome group title", 8 | "description": "Outcome group description", 9 | "vendor_guid": "customid9000", 10 | "subgroups_url": "/api/v1/accounts/1/outcome_groups/1/subgroups", 11 | "outcomes_url": "/api/v1/accounts/1/outcome_groups/1/outcomes", 12 | "import_url": "/api/v1/accounts/1/outcome_groups/1/import", 13 | "can_edit": "true" 14 | } -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKCourseDetailsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKCourseDetailsTableViewController.h 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface CKCourseDetailsTableViewController : UITableViewController 13 | 14 | @property (nonatomic, strong) CKIClient *client; 15 | @property (nonatomic, strong) CKICourse *course; 16 | @property (nonatomic, strong) NSMutableArray *courseItems; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIFile.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIFile; 12 | @class CKIFolder; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKIFile) 16 | 17 | - (RACSignal *)fetchFile:(NSString *)fileID; 18 | - (RACSignal *)deleteFile:(CKIFile *)file; 19 | - (RACSignal *)uploadFile:(NSData *)fileData ofType:(NSString *)fileType withName:(NSString *)name inFolder:(CKIFolder *)folder; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_submission_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": false, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "html_url": "http://canvas.instructure.com/api/v1/foo", 12 | "type": "Submission", 13 | "submission_id": 1234, 14 | "assignment_id": 1234 15 | } -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKTodoItemsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKTodoItemsTableViewController.h 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CKIClient; 12 | @class CKICourse; 13 | 14 | @interface CKTodoItemsTableViewController : UITableViewController 15 | 16 | @property (nonatomic, strong) CKIClient *client; 17 | @property (nonatomic, strong) NSMutableArray *todoItems; 18 | @property (nonatomic, strong) CKICourse *course; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSHTTPURLResponse+Pagination.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSHTTPURLResponse+Pagination.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 9/19/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSHTTPURLResponse (Pagination) 12 | @property (nonatomic, readonly) NSURL *currentPage; 13 | @property (nonatomic, readonly) NSURL *nextPage; 14 | @property (nonatomic, readonly) NSURL *previousPage; 15 | @property (nonatomic, readonly) NSURL *firstPage; 16 | @property (nonatomic, readonly) NSURL *lastPage; 17 | @end 18 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPage.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPage.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class CKIPage; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKIPage) 16 | 17 | - (RACSignal *)fetchPagesForContext:(id)context; 18 | 19 | - (RACSignal *)fetchPage:(NSString *)pageID forContext:(id)context; 20 | 21 | - (RACSignal *)fetchFrontPageForContext:(id)context; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 ExampleTests/CKLoginTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKLoginTests.m 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/18/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CKLoginTests : KIFTestCase 12 | 13 | @end 14 | 15 | @implementation CKLoginTests 16 | 17 | - (void)beforeAll 18 | { 19 | [tester waitForTappableViewWithAccessibilityLabel:@"Login Button"]; 20 | } 21 | 22 | - (void)testSuccessfulLogin 23 | { 24 | [tester tapViewWithAccessibilityLabel:@"Login Button"]; 25 | 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamSubmissionItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamSubmissionItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamItem.h" 10 | 11 | @interface CKIActivityStreamSubmissionItem : CKIActivityStreamItem 12 | 13 | /** 14 | The ID of the submission. 15 | */ 16 | @property (nonatomic, copy) NSString *submissionID; 17 | 18 | /** 19 | The ID of the assignment this submission pertains to. 20 | */ 21 | @property (nonatomic, copy) NSString *assignmentID; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPollChoice.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPollChoice.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | #import "CKIPoll.h" 11 | #import "CKIPollChoice.h" 12 | 13 | @interface CKIClient (CKIPollChoice) 14 | 15 | - (RACSignal *)fetchPollChoicesForPoll:(CKIPoll *)poll; 16 | - (RACSignal *)fetchPollChoiceWithId:(NSString *)pollChoiceId fromPoll:(CKIPoll *)poll; 17 | - (RACSignal *)createPollChoice:(CKIPollChoice *)pollChoice forPoll:(CKIPoll *)poll; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_message_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": false, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "html_url": "http://canvas.instructure.com/api/v1/foo", 12 | "type": "Message", 13 | "message_id": 1234, 14 | "notification_category": "Assignment Graded" 15 | } -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKICourse.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKICourse.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class RACSignal, CKICourse; 12 | 13 | @interface CKIClient (CKICourse) 14 | 15 | - (RACSignal *)fetchCoursesForCurrentUser; 16 | 17 | - (RACSignal *)fetchCoursesForCurrentUserCurrentDomain; 18 | 19 | - (RACSignal *)courseWithUpdatedPermissionsSignalForCourse:(CKICourse *)course; 20 | 21 | - (RACSignal *)fetchCourseWithCourseID:(NSString *)courseID; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIOutcomeGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIOutcomeGroup.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/20/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class CKIOutcomeGroup; 13 | 14 | @interface CKIClient (CKIOutcomeGroup) 15 | 16 | - (RACSignal *)fetchRootOutcomeGroupForCourse:(CKICourse *)course; 17 | - (RACSignal *)fetchOutcomeGroupForCourse:(CKICourse *)course id:(NSString *)identifier; 18 | - (RACSignal *)fetchSubGroupsForOutcomeGroup:(CKIOutcomeGroup *)group; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_conversation_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": false, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "html_url": "http://canvas.instructure.com/api/v1/foo", 12 | "type": "Conversation", 13 | "conversation_id": 1234, 14 | "private": true, 15 | "participant_count": 3, 16 | } -------------------------------------------------------------------------------- /CanvasKit/Models/Live Assessments/CKILiveAssessmentResult.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKILiveAssessmentResult.h 3 | // CanvasKit 4 | // 5 | // Created by Derrick Hathaway on 6/9/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @class CKILiveAssessment; 12 | 13 | @interface CKILiveAssessmentResult : CKIModel 14 | @property (nonatomic) BOOL passed; 15 | @property (nonatomic) NSDate *assessedAt; 16 | @property (nonatomic) NSString *assessedUserID; 17 | @property (nonatomic) NSString *assessorUserID; 18 | 19 | @property (nonatomic) CKILiveAssessment *context; 20 | @end 21 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIAccountDomain.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Brandon Pluim on 3/3/15. 3 | // Copyright (c) 2015 Instructure. All rights reserved. 4 | // 5 | 6 | #import "CKIClient+CKIAccountDomain.h" 7 | #import "CKIAccountDomain.h" 8 | 9 | @implementation CKIClient (CKIAccountDomain) 10 | 11 | + (RACSignal *)fetchAccountDomains { 12 | CKIClient *tempClient = [[CKIClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://canvas.instructure.com"]]; 13 | NSString *path = @"api/v1/accounts/search"; 14 | return [tempClient fetchResponseAtPath:path parameters:nil modelClass:[CKIAccountDomain class] context:nil]; 15 | } 16 | 17 | @end -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIService.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIService.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIClient+CKIService.h" 11 | #include "CKIService.h" 12 | 13 | @implementation CKIClient (CKIService) 14 | 15 | - (RACSignal *)fetchService 16 | { 17 | NSString *path = [CKIRootContext.path stringByAppendingPathComponent:@"services/kaltura"]; 18 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIService class] context:nil]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIAssignment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIAssignment.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIAssignment; 12 | @class CKICourse; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKIAssignment) 16 | 17 | - (RACSignal *)fetchAssignmentsForContext:(id)context; 18 | - (RACSignal *)fetchAssignmentsForContext:(id)context includeSubmissions:(BOOL)includeSubmissions; 19 | - (RACSignal *)updateMutedForAssignment:(CKIAssignment *)assignment; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIDiscussionTopic.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIDiscussionTopic.h 3 | // CanvasKit 4 | // 5 | // Created by derrick on 12/13/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse, CKIDiscussionTopic; 12 | 13 | @interface CKIClient (CKIDiscussionTopic) 14 | - (RACSignal *)fetchDiscussionTopicsForContext:(id)context; 15 | - (RACSignal *)fetchDiscussionTopicForContext:(id)context topicID:(NSString *)topicID; 16 | - (RACSignal *)fetchAnnouncementsForContext:(id)context; 17 | 18 | - (RACSignal *)markTopicAsRead:(CKIDiscussionTopic *)topic; 19 | @end 20 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIModuleItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIModuleItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIModule; 12 | @class CKIModuleItem; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKIModuleItem) 16 | 17 | - (RACSignal *)fetchModuleItem:(NSString *)moduleItemID forModule:(CKIModule *)module; 18 | 19 | - (RACSignal *)fetchModuleItemsForModule:(CKIModule *)module; 20 | 21 | - (RACSignal *)markModuleItemAsDone:(CKIModuleItem *)item; 22 | 23 | - (RACSignal *)markModuleItemAsRead:(CKIModuleItem *)item; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIMediaServer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIMediaServer.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 11/25/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CKIMediaServer : NSObject 12 | @property (nonatomic, assign, getter = isEnabled) BOOL enabled; 13 | @property (nonatomic, strong) NSURL *domain; 14 | @property (nonatomic, strong) NSURL *resourceDomain; 15 | @property (nonatomic, strong) NSString *partnerId; 16 | 17 | - (id)initWithInfo:(NSDictionary *)info; 18 | 19 | // API URLs 20 | - (NSURL *)apiURLAdd; 21 | - (NSURL *)apiURLUpload; 22 | - (NSURL *)apiURLAddFromUploadedFile; 23 | @end 24 | -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSDictionary+DictionaryByAddingObjectsFromDictionary.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+DictionaryByAddingObjectsFromDictionary.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 9/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 10 | 11 | @implementation NSDictionary (DictionaryByAddingObjectsFromDictionary) 12 | 13 | - (NSDictionary *)dictionaryByAddingObjectsFromDictionary:(NSDictionary *)dictionary 14 | { 15 | NSMutableDictionary *mutableCopy = [self mutableCopy]; 16 | [mutableCopy addEntriesFromDictionary:dictionary]; 17 | return [mutableCopy copy]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIOutcome.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIOutcome.m 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/20/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIOutcome.h" 10 | #import "CKIClient+CKIModel.h" 11 | 12 | #import 13 | #import "CKIOutcome.h" 14 | 15 | @implementation CKIClient (CKIOutcome) 16 | 17 | - (RACSignal *)refreshOutcome:(CKIOutcome *)outcome courseID:(NSString *)courseID 18 | { 19 | return [[self refreshModel:outcome parameters:nil] map:^id(CKIOutcome *outcome) { 20 | outcome.courseID = courseID; 21 | return outcome; 22 | }]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKITab.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKITab.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CKIClient+CKITab.h" 12 | #import "CKITab.h" 13 | #import "CKICourse.h" 14 | #import "CKIGroup.h" 15 | 16 | @implementation CKIClient (CKITab) 17 | 18 | - (RACSignal *)fetchTabsForContext:(id)context 19 | { 20 | NSString *path = [[context path] stringByAppendingPathComponent:@"tabs"]; 21 | return [self fetchResponseAtPath:path parameters:@{@"include": @[@"external"]} modelClass:[CKITab class] context:context]; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/rubric_criterion.json: -------------------------------------------------------------------------------- 1 | { 2 | "points": 9.5, 3 | "id": "crit1", 4 | "description": "Criterion 1", 5 | "long_description": "Here is a longer description.", 6 | "ratings": [ 7 | { 8 | "points": 9.5, 9 | "id": "rat1", 10 | "description": "Full marks" 11 | }, 12 | { 13 | "points": 7, 14 | "id": "rat2", 15 | "description": "Partial answer" 16 | }, 17 | { 18 | "points": 0, 19 | "id": "rat3", 20 | "description": "No marks" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSArray+CKIAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+CKIAdditions.m 3 | // CanvasKit 4 | // 5 | // Created by Ben Kraus on 12/2/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "NSArray+CKIAdditions.h" 10 | 11 | @implementation NSArray (CKIAdditions) 12 | 13 | - (NSArray *)arrayByMappingValues:(NSDictionary *)valueMapping 14 | { 15 | NSMutableArray *array = [self mutableCopy]; 16 | for (NSUInteger i = 0; i < array.count; ++i) { 17 | id item = array[i]; 18 | id newValue = [valueMapping objectForKey:item]; 19 | if (newValue != nil) { 20 | array[i] = newValue; 21 | } 22 | } 23 | return [array copy]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /CanvasKit/Models/Rubric/CKIRubric.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubric.m 3 | // Created by Jason Larsen on 5/20/14. 4 | // 5 | 6 | #import "CKIRubric.h" 7 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 8 | 9 | @interface CKIRubric () 10 | @end 11 | 12 | @implementation CKIRubric 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | NSDictionary *keyPaths = @{ 16 | @"title": @"title", 17 | @"pointsPossible": @"points_possible", 18 | @"allowsFreeFormCriterionComments": @"free_form_criterion_comments" 19 | }; 20 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 21 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 22 | } 23 | 24 | @end -------------------------------------------------------------------------------- /CanvasKit/Models/CKIAPIV1.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIAPIV1.m 3 | // CanvasKit 4 | // 5 | // Created by derrick on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIAPIV1.h" 10 | 11 | @implementation CKIAPIV1 12 | + (instancetype)context { 13 | static CKIAPIV1 *apiV1; 14 | static dispatch_once_t onceToken; 15 | dispatch_once(&onceToken, ^{ 16 | apiV1 = [CKIAPIV1 new]; 17 | }); 18 | return apiV1; 19 | } 20 | 21 | - (NSString *)path 22 | { 23 | return @"/api/v1"; 24 | } 25 | 26 | - (void)setContext:(id)context 27 | { 28 | [self doesNotRecognizeSelector:_cmd]; 29 | } 30 | 31 | - (id)context { 32 | return nil; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_announcement_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": false, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "html_url": "http://canvas.instructure.com/api/v1/foo", 12 | "type": "Announcement", 13 | "announcement_id": 1234, 14 | "total_root_discussion_entries": 5, 15 | "require_initial_post": true, 16 | "user_has_posted": true, 17 | "root_discussion_entries": {} 18 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/external_tool.json: -------------------------------------------------------------------------------- 1 | { 2 | "consumer_key": "test", 3 | "created_at": "2013-07-29T21:28:47Z", 4 | "description": "This example LTI Tool Provider supports LIS Outcome pass-back and the content extension.", 5 | "domain": "lti-tool-provider.herokuapp.com", 6 | "id": 24506, 7 | "name": "LTI Test Tool", 8 | "updated_at": "2013-07-29T21:28:47Z", 9 | "url": "http://lti-tool-provider.herokuapp.com/lti_tool", 10 | "privacy_level": "public", 11 | "custom_fields":{"key":"value", "key2":"value2"}, 12 | "workflow_state": "public", 13 | "vendor_help_link": "http://lti-tool-provider.herokuapp.com/lti_tool/help", 14 | "icon_url": "http://lti-tool-provider.herokuapp.com/selector.png" 15 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/folder.json: -------------------------------------------------------------------------------- 1 | { 2 | "context_type":"Course", 3 | "context_id":1401, 4 | "files_count":10, 5 | "position":3, 6 | "updated_at":"2012-07-06T14:58:50Z", 7 | "folders_url":"https://www.example.com/api/v1/folders/2937/folders", 8 | "files_url":"https://www.example.com/api/v1/folders/2937/files", 9 | "full_name":"course files/11folder", 10 | "lock_at":"2012-07-06T14:58:50Z", 11 | "id":2937, 12 | "folders_count":0, 13 | "name":"11folder", 14 | "parent_folder_id":2934, 15 | "created_at":"2012-07-06T14:58:50Z", 16 | "unlock_at":"2012-07-06T14:58:50Z", 17 | "hidden":false, 18 | "hidden_for_user":false, 19 | "locked":true, 20 | "locked_for_user":false 21 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/activity_stream_discussion_topic_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": "2011-07-13T09:12:00Z", 3 | "updated_at": "2011-07-25T08:52:41Z", 4 | "id": 1234, 5 | "title": "Stream Item Subject", 6 | "message": "This is the body text of the activity stream item. It is plain-text, and can be multiple paragraphs.", 7 | "read_state": false, 8 | "context_type": "course", 9 | "course_id": 1, 10 | "group_id": 1, 11 | "html_url": "http://canvas.instructure.com/api/v1/foo", 12 | "type": "DiscussionTopic", 13 | "discussion_topic_id": 1234, 14 | "total_root_discussion_entries": 5, 15 | "require_initial_post": true, 16 | "user_has_posted": true, 17 | "root_discussion_entries": {} 18 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPollSubmission.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPollSubmission.m 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/23/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIPollSubmission.h" 10 | 11 | @implementation CKIClient (CKIPollSubmission) 12 | 13 | - (RACSignal *)createPollSubmission:(CKIPollSubmission *)submission forPoll:(CKIPoll *)poll pollSession:(CKIPollSession *)session 14 | { 15 | NSString *path = [session.path stringByAppendingPathComponent:@"poll_submissions"]; 16 | return [self createModelAtPath:path parameters:@{@"poll_submissions": @[@{@"poll_choice_id": submission.pollChoiceID}]} modelClass:[CKIPollSubmission class] context:session]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamConversationItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamConversationItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamItem.h" 10 | 11 | @interface CKIActivityStreamConversationItem : CKIActivityStreamItem 12 | 13 | /** 14 | This conversation item is private. 15 | */ 16 | @property (nonatomic) BOOL isPrivate; 17 | 18 | /** 19 | The number of participants in the conversation. 20 | */ 21 | @property (nonatomic) NSUInteger participantCount; 22 | 23 | /** 24 | The unique identifier for the conversation to which 25 | this stream item refers. 26 | */ 27 | @property (nonatomic, copy) NSString *conversationID; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKUserDetailsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKUserDetailsViewController.h 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/13/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface CKUserDetailsViewController : UIViewController 14 | 15 | @property (nonatomic, strong) CKIClient *client; 16 | @property (weak, nonatomic) IBOutlet UIImageView *profileImageView; 17 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 18 | @property (weak, nonatomic) IBOutlet UILabel *descriptionLabel; 19 | 20 | - (IBAction)logoutUser:(id)sender; 21 | - (IBAction)viewTodoItems:(id)sender; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIContext.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIContext.h 3 | // CanvasKit 4 | // 5 | // Created by derrick on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol CKIContext 12 | 13 | /** 14 | The parent object of this object, if any. 15 | 16 | e.g. The parent object of a Submission is the Assignment object 17 | that was used to fetch it. 18 | */ 19 | @property (nonatomic) id context; 20 | 21 | /** 22 | The api path of the object. 23 | 24 | e.g. An assignment's path might be /api/v1/courses/823991/assignments/322 25 | */ 26 | @property (nonatomic, readonly) NSString *path; 27 | 28 | @end 29 | 30 | #import "CKIAPIV1.h" 31 | #define CKIRootContext [CKIAPIV1 context] -------------------------------------------------------------------------------- /CanvasKit/Models/CKIPollSession.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIPollSession.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIPollSession : CKIModel 12 | 13 | @property (nonatomic) BOOL isPublished; 14 | 15 | @property (nonatomic) BOOL hasPublicResults; 16 | 17 | @property (nonatomic, copy) NSString *courseID; 18 | 19 | @property (nonatomic, copy) NSString *sectionID; 20 | 21 | @property (nonatomic, copy) NSString *pollID; 22 | 23 | @property (nonatomic, copy) NSDate *created; 24 | 25 | @property (nonatomic, copy) NSDictionary *results; 26 | 27 | @property (nonatomic) BOOL hasSubmitted; 28 | 29 | @property (nonatomic, copy) NSArray *submissions; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /CanvasKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 10 | 12 | 13 | 15 | 16 | 18 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKISubmissionRecord.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKISubmissionRecord.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 9/5/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | #import "CKIAssignment.h" 11 | #import 12 | 13 | @interface CKIClient (CKISubmissionRecord) 14 | 15 | - (RACSignal *)fetchSubmissionRecordsForAssignment:(CKIAssignment *)assignment; 16 | - (RACSignal *)fetchSubmissionRecordForAssignment:(CKIAssignment *)assignment forStudentWithID:(NSString *)studentID; 17 | - (RACSignal *)updateGrade:(NSString *)gradeString forSubmissionRecord:(CKISubmission *)submission; 18 | - (RACSignal *)addComment:(NSString *)comment forSubmissionRecord:(CKISubmission *)submission; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CanvasKitTests/CanvasKitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.instructure.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKITodoItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKITodoItem.h 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | @class CKIAssignment; 11 | 12 | @interface CKITodoItem : CKIModel 13 | 14 | @property (nonatomic, strong) NSString *type; 15 | 16 | @property (nonatomic, strong) CKIAssignment *assignment; 17 | 18 | @property (nonatomic, strong) NSURL *ignore; 19 | 20 | @property (nonatomic, strong) NSURL *ignorePermanently; 21 | 22 | @property (nonatomic, strong) NSURL *htmlUrl; 23 | 24 | @property (nonatomic) NSInteger needsGradingCount; 25 | 26 | @property (nonatomic, strong) NSString *courseID; 27 | 28 | @property (nonatomic, strong) NSString *contextType; 29 | 30 | @property (nonatomic, strong) NSString *groupID; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /CanvasKit/UIKit+CanvasKit/CKILoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKILoginViewController.h 3 | // OAuthTesting 4 | // 5 | // Created by rroberts on 8/22/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIClient.h" 11 | 12 | @interface CKILoginViewController : UIViewController 13 | 14 | @property (nonatomic, strong) UIWebView *webView; 15 | 16 | /** 17 | Block to be performed when authentication is successful 18 | */ 19 | @property (nonatomic, copy) void (^successBlock)(NSString *oauthCode); 20 | 21 | /** 22 | Block to be performed when authentication fails 23 | */ 24 | @property (nonatomic, copy) void (^failureBlock)(NSError *error); 25 | 26 | - (id)initWithRequest:(NSURLRequest *)request method:(CKIAuthenticationMethod)method; 27 | - (void)cancelOAuth; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 ExampleTests/CanvasKit 2.0 ExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | instructure.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /CanvasKitTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /CanvasKitTests/Helpers.m: -------------------------------------------------------------------------------- 1 | // 2 | // XCTestCase+Helpers.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/22/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "Helpers.h" 10 | 11 | id loadJSONFixture(NSString *fixtureName) 12 | { 13 | NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.instructure.CanvasKitTests"]; 14 | NSString *filePath = [bundle pathForResource:[fixtureName stringByDeletingPathExtension] ofType:@"json"]; 15 | NSCAssert(filePath, @"Cannot find fixture %@.json", fixtureName); 16 | 17 | NSData *data = [NSData dataWithContentsOfFile:filePath]; 18 | NSError *error = nil; 19 | id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 20 | 21 | if (error) { 22 | return nil; 23 | } 24 | return result; 25 | } 26 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIActivityStreamItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIActivityStreamItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class RACSignal; 12 | @class CKICourse; 13 | 14 | @interface CKIClient (CKIActivityStreamItem) 15 | 16 | 17 | /** 18 | Fetches the activity stream for the current user. 19 | 20 | @return A signal that will deliver pages of stream items. 21 | */ 22 | - (RACSignal *)fetchActivityStream; 23 | 24 | /** 25 | Fetches the activity stream for the given context. 26 | 27 | @param context the context for the stream i.e. a course 28 | @return a signal of pages (NSArray *) of stream items. 29 | */ 30 | - (RACSignal *)fetchActivityStreamForContext:(id)context; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKILockableModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKILockableModel.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/27/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @class CKILockInfo; 12 | 13 | /** 14 | A base class adding functionality for models that require locking. 15 | */ 16 | @interface CKILockableModel : CKIModel 17 | 18 | /** 19 | Model is in a locked state for this user. 20 | */ 21 | @property (nonatomic) BOOL lockedForUser; 22 | 23 | /** 24 | An explanation of why this is locked for the user. 25 | Present when lockedForUser is true. 26 | */ 27 | @property (nonatomic, copy) NSString *lockExplanation; 28 | 29 | /** 30 | Information for the user about the lock. Present when 31 | lockedForUser is true. 32 | */ 33 | @property (nonatomic, strong) CKILockInfo *lockInfo; 34 | @end 35 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKILockableModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKILockableModel.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/27/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKILockableModel.h" 10 | #import "CKILockInfo.h" 11 | 12 | @implementation CKILockableModel 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey 15 | { 16 | NSMutableDictionary *keyPaths = [@{ 17 | @"lockedForUser": @"locked_for_user", 18 | @"lockExplanation": @"lock_explanation", 19 | @"lockInfo": @"lock_info" 20 | } mutableCopy]; 21 | [keyPaths addEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 22 | return keyPaths; 23 | } 24 | 25 | + (NSValueTransformer *)lockInfoJSONTransformer 26 | { 27 | return [MTLValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[CKILockInfo class]]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /CanvasKitTests/attachment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 43444064, 3 | "content-type": "image/jpeg", 4 | "display_name": "profilePic-1.jpg", 5 | "filename": "profilePic.jpg", 6 | "url": "https://mobiledev.instructure.com/images/thumbnails/43444064/z5y5XR4cxQjd1VTvteYgdgp8M38eNcftbN7fG2UJ", 7 | "size": 7105, 8 | "created_at": "2013-10-21T14:41:33Z", 9 | "updated_at": "2013-10-21T14:41:35Z", 10 | "unlock_at": null, 11 | "locked": false, 12 | "hidden": false, 13 | "lock_at": null, 14 | "hidden_for_user": false, 15 | "thumbnail_url": "https://instructure-uploads.s3.amazonaws.com/thumbnails/43444064/profilePic_thumb.jpg?AWSAccessKeyId=AKIAJBQ7MOX3B5WFZGBA&Expires=1406490315&Signature=j%2BFIlGfvzsLYUCVmNwwwZMrWNMY%3D", 16 | "locked_for_user": false, 17 | "type": "attachment", 18 | "token": "c140c7cfb9a46b07128e414dca37ba9c0f80032f" 19 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/page.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "my-page-title", 3 | "title": "My Page Title", 4 | "created_at": "2012-08-06T16:46:33-06:00", 5 | "updated_at": "2012-08-08T14:25:20-06:00", 6 | "hide_from_students": true, 7 | "editing_roles": "teachers,students", 8 | "last_edited_by": { 9 | "id": 133, 10 | "display_name": "Rey del Pueblo", 11 | "avatar_image_url": "https://canvas.example.com/images/thumbnails/bm90aGluZyBoZXJl", 12 | "html_url": "https://canvas.example.com/courses/789/users/133" 13 | }, 14 | "body": "

Page Content

", 15 | "published": true, 16 | "front_page": true, 17 | "locked_for_user": true, 18 | "lock_info": { 19 | "asset_string": "wiki_page_1", 20 | "context_module": {} 21 | }, 22 | "lock_explanation": "This discussion is locked until September 1 at 12:00am" 23 | } -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/module_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 768, 3 | "position": 1, 4 | "title": "Square Roots: Irrational numbers or boxy vegetables?", 5 | "indent": 0, 6 | "type": "Assignment", 7 | "content_id": 1337, 8 | "html_url": "https://canvas.example.edu/courses/222/modules/items/768", 9 | "url": "https://canvas.example.edu/api/v1/courses/222/assignments/1337", 10 | "page_url": "my-page-title", 11 | "external_url": "https://www.example.com/externalurl", 12 | "new_tab": false, 13 | "completion_requirement": { 14 | "type": "min_score", 15 | "min_score": 10, 16 | "completed": true 17 | }, 18 | "content_details": { 19 | "points_possible": 20, 20 | "due_at": "2012-12-31T06:00:00-06:00", 21 | "unlock_at": "2012-12-31T06:00:00-06:00", 22 | "lock_at": "2012-12-31T06:00:00-06:00" 23 | } 24 | } -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKILiveAssessmentNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKILiveAssessmentNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKILiveAssessmentNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testCreateLiveAssessments() { 24 | //TODO not currently testible with default of nil for context in CKILiveAssessment 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIExternalTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIExternalTool.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class CKIExternalTool; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKIExternalTool) 16 | 17 | /** 18 | Fetches all of the external tools for a course 19 | */ 20 | - (RACSignal *)fetchExternalToolsForCourse:(CKICourse *)course; 21 | 22 | /** 23 | Get a sessionless launch url for an external tool with id. 24 | */ 25 | - (RACSignal *)fetchSessionlessLaunchURLWithURL:(NSString *)url course:(CKICourse *)course; 26 | 27 | /** 28 | Get a single external tool 29 | */ 30 | - (RACSignal *)fetchExternalToolForCourseWithExternalToolID:(NSString *)externalToolID course:(CKICourse *)course; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKISubmissionComment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKISubmissionComment.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 8/28/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | #import "CKIMediaComment.h" 12 | #import "CKISubmissionComment.h" 13 | 14 | @class CKISubmissionRecord; 15 | 16 | @interface CKIClient (CKISubmissionComment) 17 | 18 | - (RACSignal *)createSubmissionComment:(CKISubmissionComment *)comment; 19 | - (void)createCommentWithMedia:(CKIMediaComment *)mediaComment forSubmissionRecord:(CKISubmissionRecord *)submissionRecord success:(void(^)(void))success failure:(void(^)(NSError *error))failure; 20 | - (void)getThumbnailForMediaComment:(CKIMediaComment *)mediaComment ofSize:(CGSize)size success:(void(^)(UIImage *image))success failure:(void(^)(NSError *error))failure; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIAttachment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIAttachment.h 3 | // CanvasKit 4 | // 5 | // Created by derrick on 11/26/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIAttachment : CKIModel 12 | @property (nonatomic, copy) NSString *contentType; 13 | @property (nonatomic, copy) NSString *displayName; 14 | @property (nonatomic, copy) NSString *fileName; 15 | @property (nonatomic, copy) NSURL *URL; 16 | @property (nonatomic) NSUInteger size; 17 | @property (nonatomic, copy) NSDate *createdAt; 18 | @property (nonatomic, copy) NSDate *updatedAt; 19 | @property (nonatomic, copy) NSDate *unlockAt; 20 | @property (nonatomic) BOOL locked; 21 | @property (nonatomic) BOOL hidden; 22 | @property (nonatomic) BOOL hiddenForUser; 23 | @property (nonatomic) BOOL lockedForUser; 24 | @property (nonatomic, copy) NSURL *thumbnailURL; 25 | @end 26 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIModel.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CKIClient+CKIModel.h" 12 | #import "CKIModel.h" 13 | 14 | @implementation CKIClient (CKIModel) 15 | 16 | - (RACSignal *)refreshModel:(CKIModel *)model parameters:(NSDictionary *)parameters 17 | { 18 | RACSignal *mergeSignal = [[self fetchResponseAtPath:model.path parameters:parameters modelClass:[model class] context:model.context] replay]; 19 | 20 | [mergeSignal subscribeNext:^(CKIModel *updatedObject) { 21 | [model mergeValuesForKeysFromModel:updatedObject]; 22 | }]; 23 | 24 | return [mergeSignal map:^(CKIModel *updatedObject) { 25 | return model; 26 | }]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIAssignmentGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIAssignmentGroup.h 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/18/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIAssignmentGroup : CKIModel 12 | 13 | /** 14 | The name of the Assignment Group 15 | */ 16 | @property (nonatomic, strong) NSString *name; 17 | 18 | /** 19 | The position of the Assignment Group 20 | */ 21 | @property (nonatomic) NSInteger position; 22 | 23 | /** 24 | The weight of the Assignment Group 25 | */ 26 | @property (nonatomic) double weight; 27 | 28 | /** 29 | The assignments in this Assignment Group 30 | @see CKIAssignment 31 | */ 32 | @property (nonatomic, strong) NSArray *assignments; 33 | 34 | /** 35 | The grading rules that this Assignment Group has 36 | */ 37 | @property (nonatomic, strong) NSDictionary *rules; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/DiscussionSubmissionHTML/discussion_submissions.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: rgb(210,210,210); 3 | font-family: sans-serif; 4 | } 5 | 6 | #entries { 7 | margin: 75px 60px; 8 | } 9 | 10 | .entry { 11 | background: rgb(240,240,240); 12 | border: solid 1px rgba(255,255,255,1); 13 | margin: 20px 0; 14 | padding: 0px; 15 | -webkit-border-radius: 5px; 16 | color: rgb(32,32,32); 17 | -webkit-box-shadow: 0px 0px 2px rgba(12, 12, 12, 1); 18 | } 19 | 20 | .entry p { 21 | margin: 3px; 22 | font-size: 1.1em; 23 | } 24 | 25 | .entry .attachment { 26 | padding: 3px 10px 10px 10px; 27 | font-size: 1.1em; 28 | } 29 | 30 | .header { 31 | margin: 3px; 32 | } 33 | 34 | .header div.author { 35 | font-weight: bold; 36 | font-size: 12pt; 37 | } 38 | 39 | .header span.posted_at { 40 | float: right; 41 | font-size: 10pt; 42 | color: rgba(125,125,125,1); 43 | } -------------------------------------------------------------------------------- /CanvasKitTests/___ZZZ999CodeCoverageDump.m: -------------------------------------------------------------------------------- 1 | // 2 | // CodeCoverage.m 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/11/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #include 12 | 13 | extern void __gcov_flush(); 14 | 15 | @interface ___ZZZ999CodeCoverageDump : XCTestCase 16 | 17 | @end 18 | 19 | @implementation ___ZZZ999CodeCoverageDump 20 | 21 | - (void)setUp { 22 | [super setUp]; 23 | // Put setup code here. This method is called before the invocation of each test method in the class. 24 | } 25 | 26 | - (void)tearDown { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | [super tearDown]; 29 | __gcov_flush(); 30 | } 31 | 32 | - (void)testExample { 33 | XCTAssert(YES, @"Pass"); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSString+CKIAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+CKIAdditions.m 3 | // OAuthTesting 4 | // 5 | // Created by rroberts on 8/23/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "NSString+CKIAdditions.h" 10 | 11 | @implementation NSString (CKIAdditions) 12 | 13 | - (NSDictionary *)queryParameters { 14 | NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 15 | 16 | NSArray *pairs = [self componentsSeparatedByString:@"&"]; 17 | for (NSString *pair in pairs) { 18 | if (pair.length == 0) { 19 | continue; 20 | } 21 | NSArray *things = [pair componentsSeparatedByString:@"="]; 22 | NSString *key = things[0]; 23 | id value = @""; 24 | if (things.count > 1) { 25 | value = things[1]; 26 | } 27 | dict[key] = value; 28 | } 29 | return dict; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /CanvasKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKISection.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKISection.m 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/12/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKISection.h" 10 | #import "CKISection.h" 11 | 12 | @implementation CKIClient (CKISection) 13 | 14 | - (RACSignal *)fetchSectionsForCourse:(CKICourse *)course 15 | { 16 | NSString *path = [course.path stringByAppendingPathComponent:@"sections"]; 17 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKISection class] context:course]; 18 | } 19 | 20 | - (RACSignal *)fetchSectionWithID:(NSString *)sectionID 21 | { 22 | NSString *path = [[CKIRootContext.path stringByAppendingPathComponent:@"sections"] stringByAppendingPathComponent:sectionID]; 23 | return [self fetchResponseAtPath:path parameters:0 modelClass:[CKISection class] context:nil]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking/CKIModel+NetworkingSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIModel+NetworkingSpec.m 3 | // CanvasKit 4 | // 5 | // Created by derrick on 11/5/13. 6 | // Copyright 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "Kiwi.h" 10 | #import "CKIClient+TestingClient.h" 11 | #import "CKIModel+Networking.h" 12 | 13 | SPEC_BEGIN(CKIModel_NetworkingSpec) 14 | 15 | describe(@"A CKIModel", ^{ 16 | [CKIClient useTestClient]; 17 | context(@"when fetching a model by ID", ^{ 18 | CKIModel *model = [CKIModel modelWithID:@"foo"]; 19 | it(@"should call the path method", ^{ 20 | [[CKIClient currentClient] returnResponseObject:@{@"id": @(1234)} forPath:@"path"]; 21 | [[model should] receive:@selector(path) andReturn:@"path"]; 22 | [model refreshWithSuccess:nil failure:nil]; 23 | [[model.id should] equal:@"1234"]; 24 | }); 25 | }); 26 | }); 27 | SPEC_END 28 | -------------------------------------------------------------------------------- /CanvasKit/Models/Rubric/CKIRubricCriterionRating.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubricCriterionRating.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/29/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIRubricCriterionRating.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | 12 | @implementation CKIRubricCriterionRating 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey 15 | { 16 | NSDictionary *keyPaths = @{ 17 | @"points": @"points", 18 | @"comments": @"comments", 19 | @"ratingDescription": @"description" 20 | }; 21 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 22 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 23 | } 24 | 25 | + (NSValueTransformer *)idJSONTransformer 26 | { 27 | return nil; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamDiscussionTopicItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamDiscussionTopicItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamItem.h" 10 | 11 | /** 12 | Activity stream item for both discussions and annoucements. 13 | */ 14 | 15 | @interface CKIActivityStreamDiscussionTopicItem : CKIActivityStreamItem 16 | 17 | /** 18 | The number of root discussion entries. 19 | */ 20 | @property (nonatomic) NSInteger totalRootDiscussionEntries; 21 | 22 | /** 23 | An initial post is required. 24 | */ 25 | @property (nonatomic) BOOL requireInitialPost; 26 | 27 | /** 28 | The current user has posted to the discussion. 29 | */ 30 | @property (nonatomic) BOOL userHasPosted; 31 | 32 | /** 33 | The ID of the discussion topic. 34 | */ 35 | @property (nonatomic, copy) NSString * discussionTopicID; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPollSession.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPollSession.h 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | #import 11 | 12 | #import "CKIPollSession.h" 13 | #import "CKIPoll.h" 14 | 15 | @interface CKIClient (CKIPollSession) 16 | 17 | - (RACSignal *)createPollSession:(CKIPollSession *)session forPoll:(CKIPoll *)poll; 18 | - (RACSignal *)closePollSession:(CKIPollSession *)session; 19 | - (RACSignal *)publishPollSession:(CKIPollSession *)session; 20 | - (RACSignal *)deletePollSession:(CKIPollSession *)session; 21 | - (RACSignal *)fetchOpenPollSessionsForCurrentUser; 22 | - (RACSignal *)fetchClosedPollSessionsForCurrentUser; 23 | - (RACSignal *)fetchPollSessionsForPoll:(CKIPoll *)poll; 24 | - (RACSignal *)fetchResultsForPollSession:(CKIPollSession *)pollSession; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "size":4, 3 | "content-type":"text/plain", 4 | "url":"http://www.example.com/files/569/download?download_frd=1/u0026verifier=c6HdZmxOZa0Fiin2cbvZeI8I5ry7yqD7RChQzb6P", 5 | "id":569, 6 | "display_name":"file.txt", 7 | "created_at":"2012-07-06T14:58:50Z", 8 | "updated_at":"2012-07-06T14:58:50Z", 9 | "unlock_at":"2012-07-06T14:58:50Z", 10 | "locked":false, 11 | "hidden":false, 12 | "lock_at":"2012-07-06T14:58:50Z", 13 | "locked_for_user":false, 14 | "lock_info":{ 15 | "asset_string":"file_569", 16 | "unlock_at":"2013-01-01T00:00:00-06:00", 17 | "lock_at":"2013-02-01T00:00:00-06:00", 18 | "context_module":{}, 19 | "manually_locked":true 20 | }, 21 | "lock_explanation":"This assignment is locked until September 1 at 12:00am", 22 | "hidden_for_user":true, 23 | "thumbnail_url":"http://www.instructure.testing/this/url" 24 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIQuiz.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIQuiz.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIQuiz.h" 10 | #import "CKIQuiz.h" 11 | #import "CKICourse.h" 12 | 13 | @implementation CKIClient (CKIQuiz) 14 | 15 | - (RACSignal *)fetchQuiz:(NSString *)quizID forCourse:(CKICourse *)course 16 | { 17 | NSString *path = [course.path stringByAppendingPathComponent:@"quizzes"]; 18 | path = [path stringByAppendingPathComponent:quizID]; 19 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIQuiz class] context:course]; 20 | } 21 | 22 | - (RACSignal *)fetchQuizzesForCourse:(CKICourse *)course 23 | { 24 | NSString *path = [course.path stringByAppendingPathComponent:@"quizzes"]; 25 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIQuiz class] context:course]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /CanvasKitTests/Helpers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Helpers.swift 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 7/3/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class Helpers: NSObject { 12 | 13 | class func loadJSONFixture(fixtureName: String) -> AnyObject? { 14 | 15 | 16 | var bundle = NSBundle(forClass: Helpers.self) 17 | var filePath = bundle.pathForResource(fixtureName, ofType: "json") 18 | println("filePath: \(filePath)") 19 | 20 | var data = NSData(contentsOfFile: filePath!) 21 | 22 | println("data = \(NSString(data: data!, encoding:NSUTF8StringEncoding))") 23 | var result: AnyObject? = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: nil) 24 | 25 | println("result = \(result)") 26 | 27 | return result 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /CanvasKitTests/Models/CKIClient+CKIModelSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIModel+NetworkingSpec.m 3 | // CanvasKit 4 | // 5 | // Created by derrick on 11/5/13. 6 | // Copyright 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "Kiwi.h" 10 | #import "CKIClient+TestingClient.h" 11 | #import "CKIClient+CKIModel.h" 12 | #import "CKIModel.h" 13 | 14 | SPEC_BEGIN(CKIModel_NetworkingSpec) 15 | 16 | describe(@"A CKIModel", ^{ 17 | CKIClient *testClient = [CKIClient testClient]; 18 | context(@"when fetching a model by ID", ^{ 19 | CKIModel *model = [CKIModel modelWithID:@"foo"]; 20 | it(@"should call the path method", ^{ 21 | [testClient returnResponseObject:@{@"id": @(1234)} forPath:@"path"]; 22 | [[model should] receive:@selector(path) andReturn:@"path"]; 23 | [testClient refreshModel:model success:nil failure:nil]; 24 | [[model.id should] equal:@"1234"]; 25 | }); 26 | }); 27 | }); 28 | SPEC_END 29 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamAnnouncementItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamAnnouncementItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamAnnouncementItem.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIActivityStreamAnnouncementItem 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"announcementID": @"announcement_id" 19 | }; 20 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 21 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 22 | } 23 | 24 | + (NSValueTransformer *)announcementIDJSONTransformer 25 | { 26 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamMessageItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamMessageItem.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamItem.h" 10 | 11 | /** 12 | Generic notification message for letting students know things 13 | like an assignment was graded. 14 | */ 15 | @interface CKIActivityStreamMessageItem : CKIActivityStreamItem 16 | 17 | /** 18 | The category of notification. Can be any of the following: 19 | - "Assignment Created" 20 | - "Assignment Changed" 21 | - "Assignment Due Date Changed" 22 | - "Assignment Graded" 23 | - "Assignment Submitted Late" 24 | - "Grade Weight Changed" 25 | - "Group Assignment Submitted Late" 26 | - "Due Date" 27 | */ 28 | @property (nonatomic, copy) NSString *notificationCategory; 29 | 30 | /** 31 | The ID of the message. 32 | */ 33 | @property (nonatomic, copy) NSString *messageID; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking/CKIClient+CKIFileSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIFileSpec.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 10/9/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIClient+TestingClient.h" 11 | #import "CKIClient+CKIFile.h" 12 | #import "CKIFile.h" 13 | 14 | SPEC_BEGIN(CKIClient_CKIFileSpec) 15 | 16 | describe(@"A CKIFile", ^{ 17 | context(@"when fetching a single file", ^{ 18 | CKIClient *testClient = [CKIClient testClient]; 19 | NSString *testPath = @"/api/v1/files/123"; 20 | 21 | it(@"should call the CKIClient helper with the correct path", ^{ 22 | [[testClient should] receive:@selector(fetchModelAtPath:parameters:modelClass:context:success:failure:) withArguments:testPath, any(), any(), any(), any(), any()]; 23 | [testClient fetchFile:@"123" success:nil failure:nil]; 24 | }); 25 | }); 26 | }); 27 | 28 | SPEC_END -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIAssignmentGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIAssignmentGroup.h 3 | // CanvasKit 4 | // 5 | // Created by Miles Wright on 1/8/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class RACSignal; 13 | 14 | @interface CKIClient (CKIAssignmentGroup) 15 | 16 | /** 17 | Fetches the assignment groups for the given context. 18 | 19 | @param gradingPeriodID the id of the desired grading period. Pass nil for all. 20 | */ 21 | - (RACSignal *)fetchAssignmentGroupsForContext:(id )context gradingPeriodID:(NSString *)gradingPeriodID scopeAssignmentsToStudent:(BOOL)scopeAssignmentsToStudent; 22 | 23 | - (RACSignal *)fetchAssignmentGroupsForContext:(id )context includeAssignments:(BOOL)includeAssignments gradingPeriodID:(NSString *)gradingPeriodID includeSubmissions:(BOOL)includeSubmissions scopeAssignmentsToStudent:(BOOL)scopeAssignmentsToStudent; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIFavorite.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIFavorite.m 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIFavorite.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIFavorite 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"contextID": @"context_id", 19 | @"contextType": @"context_type" 20 | }; 21 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 22 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 23 | } 24 | 25 | + (NSValueTransformer *)contextIDJSONTransformer 26 | { 27 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /CanvasKitTests/Models/CKIActivityStreamMessageItemSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamMessageItemSpec.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Helpers.h" 11 | #import "CKIISO8601DateMatcher.h" 12 | 13 | #import "CKIActivityStreamMessageItem.h" 14 | 15 | SPEC_BEGIN(CKIActivityStreamMessageItemSpec) 16 | 17 | registerMatchers(@"CKI"); 18 | 19 | describe(@"A dicussion topic activity stream item", ^{ 20 | context(@"when created from json fixture", ^{ 21 | NSDictionary *json = loadJSONFixture(@"activity_stream_message_item"); 22 | CKIActivityStreamMessageItem *streamItem = [CKIActivityStreamMessageItem modelFromJSONDictionary:json]; 23 | 24 | it(@"gets the notification category", ^{ 25 | [[streamItem.notificationCategory should] equal:@"Assignment Graded"]; 26 | }); 27 | }); 28 | }); 29 | 30 | SPEC_END -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamMessageItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamMessageItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamMessageItem.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIActivityStreamMessageItem 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"notificationCategory": @"notification_category", 19 | @"messageID": @"message_id" 20 | }; 21 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 22 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 23 | } 24 | 25 | + (NSValueTransformer *)messageIDJSONTransformer 26 | { 27 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 28 | } 29 | 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIAssignmentGroup.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIAssignmentGroup.m 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/18/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIAssignmentGroup.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "CKIAssignment.h" 12 | 13 | @implementation CKIAssignmentGroup 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"name": @"name", 19 | @"position": @"position", 20 | @"weight": @"group_weight", 21 | @"assignments": @"assignments", 22 | @"rules": @"rules" 23 | }; 24 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 25 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 26 | } 27 | 28 | + (NSValueTransformer *)assignmentsJSONTransformer 29 | { 30 | return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:[CKIAssignment class]]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamConferenceItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamConferenceItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamConferenceItem.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIActivityStreamConferenceItem 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"conferenceID": @"web_conference_id" 19 | }; 20 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 21 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 22 | } 23 | 24 | + (NSValueTransformer *)conferenceIDJSONTransformer 25 | { 26 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIOutcomeLink.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIOutcomeLink.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @class CKIOutcomeGroup; 12 | @class CKIOutcome; 13 | 14 | @interface CKIOutcomeLink : CKIModel 15 | 16 | /** 17 | The context type of the outcome. 18 | */ 19 | @property (nonatomic, copy) NSString *contextType; 20 | 21 | /** 22 | The context owning the outcome. may be null for global outcomes. 23 | */ 24 | @property (nonatomic, copy) NSString *contextID; 25 | 26 | /** 27 | The URL for fetching/updating the outcome 28 | */ 29 | @property (nonatomic, copy) NSString *url; 30 | 31 | /** 32 | OutcomeGroup object representing the outcome group of this outcome link 33 | */ 34 | @property (nonatomic, copy) CKIOutcomeGroup *outcomeGroup; 35 | 36 | /** 37 | Abbreviated outcome object representing the outcome linked to 38 | */ 39 | @property (nonatomic, copy) CKIOutcome *outcome; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CanvasKit/Helpers/NSValueTransformer+CKIPredefinedTransformerAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSValueTransformer+CKIPredefinedTransformerAdditions.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/26/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | The name for a value transfomer that converts NSNumbers to NSStrings and back. 13 | */ 14 | extern NSString * const CKINumberStringTransformerName; 15 | 16 | /** 17 | The name for a value transfomer that converts NSNumbers or NSStrings to NSStrings. 18 | */ 19 | extern NSString * const CKINumberOrStringToStringTransformerName; 20 | 21 | /** 22 | The name for a value transfomer that converts ISO8601 date-strings to NSDates and back. 23 | */ 24 | extern NSString * const CKIDateTransformerName; 25 | 26 | /** 27 | The name for a value transfomer that converts the dictionary returned by the API into CKIRubricAssessments and back. 28 | */ 29 | extern NSString * const CKIRubricAssessmentTransformerName; 30 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamCollaborationItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamCollaborationItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamCollaborationItem.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIActivityStreamCollaborationItem 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"collaborationID": @"collaboration_id" 19 | }; 20 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 21 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 22 | } 23 | 24 | + (NSValueTransformer *)collaborationIDJSONTransformer 25 | { 26 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIModule.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIModule.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CKIClient+CKIModule.h" 12 | #import "CKICourse.h" 13 | #import "CKIModule.h" 14 | 15 | @implementation CKIClient (CKIModule) 16 | 17 | - (RACSignal *)fetchModulesForCourse:(CKICourse *)course 18 | { 19 | NSString *path = [course.path stringByAppendingPathComponent:@"modules"]; 20 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIModule class] context:course]; 21 | } 22 | 23 | - (RACSignal *)fetchModuleWithID:(NSString *)moduleID forCourse:(CKICourse *)course 24 | { 25 | NSString *path = [course.path stringByAppendingPathComponent:@"modules"]; 26 | path = [path stringByAppendingPathComponent:moduleID]; 27 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIModule class] context:course]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIModule.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | @class CKIModule; 13 | @class RACSignal; 14 | 15 | @interface CKIClient (CKIModule) 16 | 17 | /** 18 | Fetch all the modules for a given course. 19 | 20 | @param course the course that the modules are in 21 | @param success the block to be executed if the API call succeeds 22 | @param failure the block to be executed if the API call fails 23 | */ 24 | - (RACSignal *)fetchModulesForCourse:(CKICourse *)course; 25 | 26 | /** 27 | Fetch a specific module for a course. 28 | 29 | @param course the course that the module is in 30 | @param success the block to be executed if the API call succeeds 31 | @param failure the block to be executed if the API call fails 32 | */ 33 | - (RACSignal *)fetchModuleWithID:(NSString *)moduleID forCourse:(CKICourse *)course; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/CKISubmissionComment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKISubmissionComment.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 9/8/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @class CKIUser, CKIMediaComment; 12 | 13 | @interface CKISubmissionComment : CKIModel 14 | 15 | /** 16 | The comment text. 17 | */ 18 | @property (nonatomic, copy) NSString *comment; 19 | 20 | /** 21 | The date the comment was made; 22 | */ 23 | @property (nonatomic, strong) NSDate *createdAt; 24 | 25 | /** 26 | The Canvas user ID of the author of the comment. 27 | */ 28 | @property (nonatomic, copy) NSString *authorID; 29 | 30 | /** 31 | The name of the comment's author. 32 | */ 33 | @property (nonatomic, copy) NSString *authorName; 34 | 35 | /** 36 | The path for the submitters avatar. 37 | */ 38 | @property (nonatomic, copy) NSString *avatarPath; 39 | 40 | /** 41 | media comment for this submission comment 42 | */ 43 | @property (nonatomic) CKIMediaComment *mediaComment; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamConversationItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamConversationItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamConversationItem.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIActivityStreamConversationItem 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"isPrivate": @"private", 19 | @"participantCount": @"participant_count", 20 | @"conversationID": @"conversation_id" 21 | }; 22 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 23 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 24 | } 25 | 26 | + (NSValueTransformer *)conversationIDJSONTransformer 27 | { 28 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/CKISubmissionRecord.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKISubmissionRecord.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 9/5/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CanvasKit.h" 10 | #import "CKIAssignment.h" 11 | #import "CKISubmission.h" 12 | 13 | @interface CKISubmissionRecord : CKISubmission 14 | 15 | /** 16 | Comments left by graders. An array of CKISubmissionComment objects. 17 | */ 18 | @property (nonatomic, copy) NSArray *comments; 19 | 20 | /** 21 | * An array of CKISubmissions history of submissions for this particular 22 | * user on this particular assignment, in order of least to most recent. 23 | */ 24 | @property (nonatomic, copy) NSArray *submissionHistory; 25 | 26 | /** 27 | * RubricAssessment associated with submission, nil if no assessment 28 | */ 29 | @property (nonatomic, copy) CKIRubricAssessment *rubricAssessment; 30 | 31 | @property (nonatomic) CKIAssignment *context; 32 | 33 | - (BOOL)isDummySubmission; 34 | 35 | - (CKISubmission *)defaultAttempt; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIPage.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIPage.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 9/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKILockableModel.h" 10 | 11 | @class CKIUser; 12 | 13 | @interface CKIPage : CKILockableModel 14 | 15 | /** 16 | The title of the page. 17 | */ 18 | @property (nonatomic, copy) NSString *title; 19 | 20 | /** 21 | The date the page was created. 22 | */ 23 | @property (nonatomic, strong) NSDate *createdAt; 24 | 25 | /** 26 | The date the page was last updated. 27 | */ 28 | @property (nonatomic, strong) NSDate *updatedAt; 29 | 30 | /** 31 | This page is hidden from students. 32 | 33 | @note Students will never see this true; pages hidden 34 | from them will be omitted from results 35 | */ 36 | @property (nonatomic) BOOL hideFromStudents; 37 | 38 | /** 39 | The user that last edited this page. 40 | */ 41 | @property (nonatomic, readonly) CKIUser *lastEditedBy; 42 | 43 | @property (nonatomic) BOOL published; 44 | 45 | @property (nonatomic) BOOL frontPage; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking/CKIClient+CKIServiceSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIServiceSpec.m 3 | // CanvasKit 4 | // 5 | // Created by Miles Wright on 10/8/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIClient+TestingClient.h" 11 | #import "CKIClient+CKIService.h" 12 | #import "CKIService.h" 13 | 14 | SPEC_BEGIN(CKIClient_CKIServiceSpec) 15 | 16 | describe(@"A CKIService", ^{ 17 | 18 | context(@"when fetching a service", ^{ 19 | CKIClient *testClient = [CKIClient testClient]; 20 | NSString *testPath = @"/api/v1/services/kaltura"; 21 | [testClient returnResponseObject:@{} forPath:testPath]; 22 | 23 | it(@"should call the CKIClient helper with the correct path", ^{ 24 | [[testClient should] receive:@selector(fetchModelAtPath:parameters:modelClass:context:success:failure:) withArguments:testPath, any(), any(), any(), any(), any()]; 25 | [testClient fetchServiceSuccess:nil failure:nil]; 26 | }); 27 | }); 28 | }); 29 | 30 | 31 | SPEC_END -------------------------------------------------------------------------------- /CanvasKitTests/Networking/CKIClient+CKICourseSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKICourseSpec.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 10/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIClient+TestingClient.h" 11 | #import "CKIClient+CKICourse.h" 12 | #import "CKICourse.h" 13 | 14 | SPEC_BEGIN(CKIClient_CKICourseSpec) 15 | 16 | describe(@"A CKICourse", ^{ 17 | context(@"when fetching courses for the a user", ^{ 18 | CKIClient *testClient = [CKIClient testClient]; 19 | NSString *testPath = @"/api/v1/courses"; 20 | [testClient returnResponseObject:@[] forPath:testPath]; 21 | 22 | it(@"should call the CKIClient helper with the correct path", ^{ 23 | [[testClient should] receive:@selector(fetchPagedResponseAtPath:parameters:modelClass:context:success:failure:) withArguments:testPath, any(), any(), any(), any(), any()]; 24 | [testClient fetchCoursesForCurrentUserWithSuccess:nil failure:nil]; 25 | }); 26 | }); 27 | }); 28 | 29 | SPEC_END -------------------------------------------------------------------------------- /CanvasKit/Models/CKITerm.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKITerm.m 3 | // CanvasKit 4 | // 5 | // Created by derrick on 11/21/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKITerm.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKITerm 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey 15 | { 16 | NSDictionary *keyPaths = @{ 17 | @"startAt": @"start_at", 18 | @"endAt": @"end_at" 19 | }; 20 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 21 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 22 | } 23 | 24 | + (NSValueTransformer *)startAtJSONTransformer 25 | { 26 | return [NSValueTransformer valueTransformerForName:CKIDateTransformerName]; 27 | } 28 | 29 | + (NSValueTransformer *)endAtJSONTransformer 30 | { 31 | return [NSValueTransformer valueTransformerForName:CKIDateTransformerName]; 32 | } 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIActivityStreamItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIActivityStreamItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/12/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CKIClient+CKIActivityStreamItem.h" 12 | #import "CKIActivityStreamItem.h" 13 | #import "CKICourse.h" 14 | 15 | @implementation CKIClient (CKIActivityStreamItem) 16 | 17 | - (RACSignal *)fetchActivityStreamForContext:(id)context 18 | { 19 | NSString *path = context.path; 20 | 21 | if ([path isEqualToString:@"/api/v1"] || path == (id)[NSNull null] || path.length == 0){ 22 | path = @"/api/v1/users/self/activity_stream"; 23 | } 24 | 25 | NSValueTransformer *transformer = [CKIActivityStreamItem activityStreamItemTransformer]; 26 | return [self fetchResponseAtPath:path parameters:nil transformer:transformer context:nil]; 27 | } 28 | 29 | - (RACSignal *)fetchActivityStream 30 | { 31 | return [self fetchActivityStreamForContext:CKIRootContext]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/calendar_event.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1194491, 3 | "title": "Testing", 4 | "start_at": "2013-09-18T00:00:00-06:00", 5 | "end_at": "2013-09-18T00:00:00-06:00", 6 | "description": "Secret Meeting of Super Persons", 7 | "location_name": "The Bat Cave", 8 | "location_address": "300 E Super Cool Dr", 9 | "context_code": "user_4621806", 10 | "workflow_state": "active", 11 | "hidden": false, 12 | "parent_event_id": 1, 13 | "child_events_count": 0, 14 | "child_events": "", 15 | "url": "https://mobiledev.instructure.com/api/v1/calendar_events/1194491", 16 | "html_url": "https://mobiledev.instructure.com/calendar?event_id=1194491&include_contexts=user_4621806#7b2273686f77223a2267726f75705f757365725f34363231383036227d", 17 | "all_day_date": "2013-09-18", 18 | "all_day": true, 19 | "created_at": "2013-09-18T08:57:31-06:00", 20 | "updated_at": "2013-09-18T08:57:31-06:00", 21 | "reserved": false, 22 | "appointment_group_id": 987, 23 | "appointment_group_url" : "https://example.com/api/v1/appointment_groups/543", 24 | "own_reservation": false, 25 | "available_slots": 5 26 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIOutcomeLink.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIOutcomeLink.m 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIOutcomeLink.h" 10 | 11 | #import 12 | #import "CKIOutcomeLink.h" 13 | #import "CKIOutcome.h" 14 | #import "CKIOutcomeGroup.h" 15 | 16 | @implementation CKIClient (CKIOutcomeLink) 17 | 18 | - (RACSignal *)fetchOutcomeLinksForOutcomeGroup:(CKIOutcomeGroup *)group 19 | { 20 | NSString *path = [group.path stringByAppendingPathComponent:@"outcomes"]; 21 | return [[self fetchResponseAtPath:path parameters:nil modelClass:[CKIOutcomeLink class] context:group.context] map:^id(NSArray *outcomes) { 22 | 23 | [outcomes enumerateObjectsUsingBlock:^(CKIOutcomeLink *outcomeLink, NSUInteger idx, BOOL *stop) { 24 | outcomeLink.outcomeGroup = group; 25 | outcomeLink.id = [NSString stringWithFormat:@"%@-link-%@", @(idx), group.id]; 26 | }]; 27 | return outcomes; 28 | }]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKIServiceNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIServiceNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKIServiceNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testFetchService() { 24 | let client = MockCKIClient() 25 | 26 | client.fetchService() 27 | XCTAssertEqual(client.capturedPath!, "/api/v1/services/kaltura", "CKIService returned API path for testFetchService was incorrect") 28 | XCTAssertEqual(client.capturedMethod!, MockCKIClient.Method.Fetch, "CKIService API Interaction Method was incorrect") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKICalendarEvent.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKICalendarEvent.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class RACSignal; 12 | @class CKICourse; 13 | 14 | @interface CKIClient (CKICalendarEvent) 15 | 16 | /** 17 | Fetches all calendar events for the context 18 | */ 19 | - (RACSignal *)fetchCalendarEventsForContext:(id)context; 20 | 21 | /** 22 | Fetches only today's calendar events for the current user 23 | */ 24 | - (RACSignal *)fetchCalendarEventsForToday; 25 | 26 | /** 27 | Fetches the calendar events between the start date and the end date for the current user 28 | 29 | @param startDate the earlist possible date for a returned calendar event 30 | @param endDate the latest possible date for a returned calendar event 31 | */ 32 | - (RACSignal *)fetchCalendarEventsFrom:(NSDate *)startDate to:(NSDate *)endDate; 33 | 34 | /** 35 | Fetches all of the calendar events for the current user 36 | */ 37 | - (RACSignal *)fetchCalendarEvents; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIGroupCategory.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIGroupCategory.m 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 12/8/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIGroupCategory.h" 10 | 11 | #import "CKIGroupCategory.h" 12 | #import "CKIUser.h" 13 | #import "CKICourse.h" 14 | 15 | @implementation CKIClient (CKIGroupCategory) 16 | 17 | - (RACSignal *)fetchGroupCategoriesForCourse:(CKICourse *)course 18 | { 19 | NSString *path = [course.path stringByAppendingPathComponent:@"group_categories"]; 20 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIGroupCategory class] context:nil]; 21 | } 22 | 23 | - (RACSignal *)fetchUsersInGroupCategory:(CKIGroupCategory *)category 24 | { 25 | NSString *path = [CKIRootContext.path stringByAppendingPathComponent:@"group_categories"]; 26 | path = [path stringByAppendingPathComponent:category.id]; 27 | path = [path stringByAppendingPathComponent:@"users"]; 28 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIUser class] context:nil]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISection.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKISection.m 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/12/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKISection.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKISection 14 | 15 | 16 | + (NSDictionary *)JSONKeyPathsByPropertyKey 17 | { 18 | NSDictionary *keyPaths = @{ 19 | @"name": @"name", 20 | @"courseID": @"course_id", 21 | }; 22 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 23 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 24 | } 25 | 26 | - (NSString *)path 27 | { 28 | return [[self.context.path stringByAppendingPathComponent:@"sections"] stringByAppendingPathComponent:self.id]; 29 | } 30 | 31 | + (NSValueTransformer *)courseIDJSONTransformer 32 | { 33 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIFavoriteTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIFavoriteTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/23/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKIFavoriteTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | let favoriteDictionary = Helpers.loadJSONFixture("favorite") as NSDictionary 26 | let favorite = CKIFavorite(fromJSONDictionary: favoriteDictionary) 27 | 28 | XCTAssertEqual(favorite.contextID!, "1170", "Favorite contextID did not parse correctly") 29 | XCTAssertEqual(favorite.contextType!, "Course", "Favorite contextType did not parse correctly") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CanvasKit/Models/Live Assessments/CKILiveAssessment.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKILiveAssessment.m 3 | // CanvasKit 4 | // 5 | // Created by Derrick Hathaway on 6/9/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKILiveAssessment.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | 12 | @implementation CKILiveAssessment 13 | 14 | + (NSString *)keyForJSONAPIContent 15 | { 16 | return @"assessments"; 17 | } 18 | 19 | + (NSDictionary *)JSONKeyPathsByPropertyKey 20 | { 21 | NSDictionary *pathsByProperty = @{ 22 | @"context": [NSNull null], 23 | @"outcomeID": @"links.outcome", 24 | }; 25 | 26 | return [[super JSONKeyPathsByPropertyKey] dictionaryByAddingObjectsFromDictionary:pathsByProperty]; 27 | } 28 | 29 | + (NSValueTransformer *)idJSONTransformer 30 | { 31 | return [MTLValueTransformer reversibleTransformerWithBlock:^id(id value) { 32 | return value; 33 | }]; 34 | } 35 | 36 | - (NSString *)path 37 | { 38 | return [[self.context.path stringByAppendingPathComponent:@"live_assessments"] stringByAppendingPathComponent:self.id]; 39 | } 40 | @end 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | **Copyright (c) 2013, Instructure, Inc.** 2 | **All rights reserved.** 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKITabNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKITabNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKITabNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testFetchTabsForContext() { 24 | let courseDictionary = Helpers.loadJSONFixture("course") as NSDictionary 25 | let course = CKICourse(fromJSONDictionary: courseDictionary) 26 | let client = MockCKIClient() 27 | 28 | client.fetchTabsForContext(course) 29 | XCTAssertEqual(client.capturedPath!, "/api/v1/courses/1/tabs", "CKITab returned API path for testFetchTabsForContext was incorrect") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CanvasKitTests/Models/CKIActivityStreamConversationItemSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamConversationItemSpec.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Helpers.h" 11 | #import "CKIISO8601DateMatcher.h" 12 | 13 | #import "CKIActivityStreamConversationItem.h" 14 | 15 | SPEC_BEGIN(CKIActivityStreamConversationItemSpec) 16 | 17 | registerMatchers(@"CKI"); 18 | 19 | describe(@"A dicussion topic activity stream item", ^{ 20 | context(@"when created from json fixture", ^{ 21 | NSDictionary *json = loadJSONFixture(@"activity_stream_conversation_item"); 22 | CKIActivityStreamConversationItem *streamItem = [CKIActivityStreamConversationItem modelFromJSONDictionary:json]; 23 | 24 | it(@"gets boolean value for private", ^{ 25 | [[theValue(streamItem.isPrivate) should] equal:theValue(YES)]; 26 | }); 27 | 28 | it(@"gets the participant count", ^{ 29 | [[theValue(streamItem.participantCount) should] equal:theValue(3)]; 30 | }); 31 | }); 32 | }); 33 | 34 | SPEC_END -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamDiscussionTopicItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamDiscussionTopicItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamDiscussionTopicItem.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIActivityStreamDiscussionTopicItem 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"totalRootDiscussionEntries": @"total_root_discussion_entries", 19 | @"requireInitialPost": @"require_initial_post", 20 | @"userHasPosted": @"user_has_posted", 21 | @"discussionTopicID": @"discussion_topic_id" 22 | }; 23 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 24 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 25 | } 26 | 27 | + (NSValueTransformer *)discussionTopicIDJSONTransformer 28 | { 29 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIActivityStreamMessageItemTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamMessageItem.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/10/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKIActivityStreamMessageItemTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testJSONModelConversion() { 24 | let activityStreamMessageItemDictionary = Helpers.loadJSONFixture("activity_stream_message_item") as NSDictionary 25 | let streamItem = CKIActivityStreamMessageItem(fromJSONDictionary: activityStreamMessageItemDictionary) 26 | 27 | XCTAssertEqual(streamItem.notificationCategory!, "Assignment Graded", "Activity Stream Item notificationCategory was not parsed correctly") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIActivityStreamConferenceItemTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamConferenceItemTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/17/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKIActivityStreamConferenceItemTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | let activityStreamConferenceItemDictionary = Helpers.loadJSONFixture("activity_stream_conference_item") as NSDictionary 26 | let streamItem = CKIActivityStreamConferenceItem(fromJSONDictionary: activityStreamConferenceItemDictionary) 27 | 28 | XCTAssertEqual(streamItem.conferenceID!, "1234", "Stream Conference Item id was not parsed correctly") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIGroupCategory.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIGroupCategory.m 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 12/8/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIGroupCategory.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | 12 | @implementation CKIGroupCategory 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey 15 | { 16 | NSDictionary *keyPaths = @{ 17 | @"selfSignup": @"self_signup", 18 | @"autoLeader": @"auto_leader", 19 | @"contextType": @"context_type", 20 | @"accountID": @"account_id", 21 | @"groupLimit": @"group_limit", 22 | }; 23 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 24 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 25 | } 26 | 27 | - (NSString *)path 28 | { 29 | NSString *path = self.context.path; 30 | path = [path stringByAppendingPathComponent:@"group_categories"]; 31 | return [path stringByAppendingPathComponent:self.id]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKIAssignmentNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIAssignmentNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/28/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKIAssignmentNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testNotReallyMockingButKindOf() { 24 | let courseDictionary = Helpers.loadJSONFixture("course") as NSDictionary 25 | let course = CKICourse(fromJSONDictionary: courseDictionary) 26 | let client = MockCKIClient() 27 | 28 | client.fetchAssignmentsForContext(course) 29 | XCTAssertEqual(client.capturedPath!, "/api/v1/courses/\(course.id)/assignments", "Returned API path for fetchCourseWithCourseID was incorrect") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CanvasKit/Models/Rubric/CKIRubric.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubric.h 3 | // Created by Jason Larsen on 5/20/14. 4 | // 5 | 6 | #import 7 | #import "CKIModel.h" 8 | 9 | 10 | /** 11 | * Every assignment may have a rubric. The rubric is used as a template 12 | * to standardize grading on an assignment. A rubric is composed of rubric 13 | * criteria, and each individual criterion has several rating options, each 14 | * option represented by a rating object. 15 | * 16 | * @see CKIRubricCriterion 17 | * @see CKIRubricCriterionRating 18 | */ 19 | @interface CKIRubric : CKIModel 20 | 21 | /** 22 | * The title of the rubric. 23 | */ 24 | @property (nonatomic, copy) NSString *title; 25 | 26 | /** 27 | * The total number of points possible. 28 | * 29 | * @note a submission may score over 100%, and therefore the actual points 30 | * may be greater than pointsPossible. 31 | */ 32 | @property (nonatomic) double pointsPossible; 33 | 34 | /** 35 | * Indicates whether or not the grader should be presented with 36 | * the option to include a special free-form comment along with 37 | * the rating selection on a particular criterion. 38 | */ 39 | @property (nonatomic) BOOL allowsFreeFormCriterionComments; 40 | 41 | @end -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIUser.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKICourse; 12 | 13 | @interface CKIClient (CKIUser) 14 | 15 | /** 16 | Fetch all the users for the current course. 17 | 18 | @param course the course to fetch the users for 19 | */ 20 | - (RACSignal *)fetchUsersForContext:(id)context; 21 | 22 | /** 23 | Fetch all the students for the current course. 24 | 25 | @param course the course to fetch the students for 26 | */ 27 | - (RACSignal *)fetchStudentsForContext:(id)context; 28 | 29 | /** 30 | Fetch users for the current course filtered by parameters. 31 | 32 | @param parameters the parameters for fetching users in the course 33 | @param course the course to fetch the users for 34 | @param success the block to be executed if the API call succeeds 35 | @param failure the block to be executed if the API call fails 36 | */ 37 | - (RACSignal *)fetchUsersWithParameters:(NSDictionary *)parameters context:(id )context; 38 | 39 | - (RACSignal *)fetchCurrentUser; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIActivityStreamCollaborationItemTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamCollaborationItemTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/17/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKIActivityStreamCollaborationItemTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | let activityStreamCollaborationItemDictionary = Helpers.loadJSONFixture("activity_stream_collaboration_item") as NSDictionary 26 | let streamItem = CKIActivityStreamCollaborationItem(fromJSONDictionary: activityStreamCollaborationItemDictionary) 27 | 28 | XCTAssertEqual(streamItem.collaborationID!, "1234", "Stream Collaboration Item id was not parsed correctly") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIPoll.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIPoll.m 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/7/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIPoll.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIPoll 14 | 15 | + (NSString *)keyForJSONAPIContent 16 | { 17 | return @"polls"; 18 | } 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey 21 | { 22 | NSDictionary *keyPaths = @{ 23 | @"created": @"created_at" 24 | }; 25 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 26 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 27 | } 28 | 29 | + (NSValueTransformer *)idJSONTransformer 30 | { 31 | return nil; 32 | } 33 | 34 | + (NSValueTransformer *)createdJSONTransformer 35 | { 36 | return [NSValueTransformer valueTransformerForName:CKIDateTransformerName]; 37 | } 38 | 39 | - (NSString *)path 40 | { 41 | return [[self.context.path stringByAppendingPathComponent:@"polls"] stringByAppendingPathComponent:self.id]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIPollChoice.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIPollChoice.m 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIPollChoice.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIPollChoice 14 | 15 | + (NSString *)keyForJSONAPIContent 16 | { 17 | return @"poll_choices"; 18 | } 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey 21 | { 22 | NSDictionary *keyPaths = @{ 23 | @"isCorrect": @"is_correct", 24 | @"pollID": @"poll_id", 25 | @"index": @"position" 26 | }; 27 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 28 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 29 | } 30 | 31 | + (NSValueTransformer *)idJSONTransformer 32 | { 33 | return nil; 34 | } 35 | 36 | - (NSString *)path 37 | { 38 | return [[self.context.path stringByAppendingPathComponent:@"poll_choices"] stringByAppendingPathComponent:self.id]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/CKIMediaComment.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIMediaComment.h 3 | // Created by Jason Larsen on 5/8/14. 4 | // 5 | 6 | #import 7 | #import "CKIModel.h" 8 | 9 | extern NSString * const CKIMediaCommentMediaTypeAudio; 10 | extern NSString * const CKIMediaCommentMediaTypeVideo; 11 | 12 | @interface CKIMediaComment : CKIModel 13 | 14 | /** 15 | * The ID of this piece of media. Identical to the id property, 16 | * it's just that the JSON media comment object doesn't have an ID 17 | * property, and only has a mediaID property, so this is here for 18 | * a little API consistency. 19 | */ 20 | @property (nonatomic, copy) NSString *mediaID; 21 | 22 | /** 23 | * The type of content, example: "audio/mp4" or "video/mp4". 24 | */ 25 | @property (nonatomic, copy) NSString *contentType; 26 | 27 | /** 28 | * The type of media: "audio" or "video". 29 | */ 30 | @property (nonatomic, copy) NSString *mediaType; 31 | 32 | /** 33 | * The name to display for the media comment. 34 | */ 35 | @property (nonatomic, copy) NSString *displayName; 36 | 37 | /** 38 | * The URL to download the media comment file, whether it 39 | * be an image, video, or audio. 40 | */ 41 | @property (nonatomic, strong) NSURL *url; 42 | 43 | @end -------------------------------------------------------------------------------- /CanvasKit/Models/CKIActivityStreamSubmissionItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamSubmissionItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIActivityStreamSubmissionItem.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 12 | 13 | @implementation CKIActivityStreamSubmissionItem 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey 16 | { 17 | NSDictionary *keyPaths = @{ 18 | @"submissionID": @"submission_id", 19 | @"assignmentID": @"assignment_id" 20 | }; 21 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 22 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 23 | } 24 | 25 | + (NSValueTransformer *)submissionIDJSONTransformer 26 | { 27 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 28 | } 29 | 30 | + (NSValueTransformer *)assignmentIDJSONTransformer 31 | { 32 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPage.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPage.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIPage.h" 10 | #import "CKIPage.h" 11 | #import "CKICourse.h" 12 | 13 | @implementation CKIClient (CKIPage) 14 | 15 | - (RACSignal *)fetchPagesForContext:(id)context 16 | { 17 | NSString *path = [context.path stringByAppendingPathComponent:@"pages"]; 18 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIPage class] context:context]; 19 | } 20 | 21 | - (RACSignal *)fetchPage:(NSString *)pageID forContext:(id)context 22 | { 23 | NSString * path = [context.path stringByAppendingPathComponent:@"pages"]; 24 | path = [path stringByAppendingPathComponent:pageID]; 25 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIPage class] context:context]; 26 | } 27 | 28 | - (RACSignal *)fetchFrontPageForContext:(id)context 29 | { 30 | NSString * path = [context.path stringByAppendingPathComponent:@"front_page"]; 31 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIPage class] context:context]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKIOutcomeNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIOutcomeNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKIOutcomeNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testFetchOutcomeLinksForOutcomeGroup() { 24 | let outcomeDictionary = Helpers.loadJSONFixture("outcome") as NSDictionary 25 | let outcome = CKIOutcome(fromJSONDictionary: outcomeDictionary) 26 | let client = MockCKIClient() 27 | let courseID = "1" 28 | 29 | client.refreshOutcome(outcome, courseID: courseID) 30 | XCTAssertEqual(client.capturedPath!, "/api/v1/outcomes/1", "CKIOutcome returned API path for testFetchOutcomeLinksForOutcomeGroup was incorrect") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKIAssignmentGroupNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIAssignmentGroupNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKIAssignmentGroupNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testFetchAssignmentGroupsForContext() { 24 | let client = MockCKIClient() 25 | let courseDictionary = Helpers.loadJSONFixture("course") as NSDictionary 26 | let course = CKICourse(fromJSONDictionary: courseDictionary) 27 | 28 | client.fetchAssignmentGroupsForContext(course) 29 | XCTAssertEqual(client.capturedPath!, "/api/v1/courses/1/assignment_groups", "CKIAssignmentGroups returned API path for testFetchAssignmentGroupsForContext was incorrect") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIOutcome.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIOutcome.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/20/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @class CKIOutcomeGroup; 12 | 13 | @interface CKIOutcome : CKIModel 14 | 15 | /** 16 | The title for the outcome. 17 | */ 18 | @property (nonatomic, copy) NSString *title; 19 | 20 | /** 21 | The courseID for the outcome. 22 | */ 23 | @property (nonatomic, copy) NSString *courseID; 24 | 25 | /** 26 | The description for the outcome. 27 | */ 28 | @property (nonatomic, copy) NSString *details; 29 | 30 | /** 31 | The context type of the outcome. 32 | */ 33 | @property (nonatomic, copy) NSString *contextType; 34 | 35 | /** 36 | The context owning the outcome. may be null for global outcomes. 37 | */ 38 | @property (nonatomic, copy) NSString *contextID; 39 | 40 | /** 41 | The URL for fetching/updating the outcome 42 | */ 43 | @property (nonatomic, copy) NSString *url; 44 | 45 | /** 46 | maximum points possible. 47 | */ 48 | @property (nonatomic, copy) NSNumber *pointsPossible; 49 | 50 | /** 51 | points necessary to demonstrate mastery outcomes. 52 | */ 53 | @property (nonatomic, copy) NSNumber *masteryPoints; 54 | 55 | 56 | @end -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKIOutcomeLinkNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIOutcomeLinkNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKIOutcomeLinkNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testFetchOutcomeLinksForOutcomeGroup() { 24 | let outcomeGroupDictionary = Helpers.loadJSONFixture("outcome_group") as NSDictionary 25 | let outcomeGroup = CKIOutcomeGroup(fromJSONDictionary: outcomeGroupDictionary) 26 | let client = MockCKIClient() 27 | 28 | client.fetchOutcomeLinksForOutcomeGroup(outcomeGroup) 29 | XCTAssertEqual(client.capturedPath!, "/api/v1/outcome_groups/1/outcomes", "CKIOutcomeLink returned API path for testFetchOutcomeLinksForOutcomeGroup was incorrect") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/quiz.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 5, 3 | "title": "Hamlet Act 3 Quiz", 4 | "html_url": "http://canvas.example.edu/courses/1/quizzes/2", 5 | "mobile_url": "http://canvas.example.edu/courses/1/quizzes/2?persist_healdess=1&force_user=1", 6 | "description": "This is a quiz on Act 3 of Hamlet", 7 | "quiz_type": "assignment", 8 | "assignment_group_id": 3, 9 | "time_limit": 5, 10 | "shuffle_answers": false, 11 | "hide_results": "always", 12 | "show_correct_answers": true, 13 | "scoring_policy": "keep_highest", 14 | "allowed_attempts": 3, 15 | "one_question_at_a_time": false, 16 | "question_count": 12, 17 | "points_possible": 20, 18 | "cant_go_back": false, 19 | "access_code": "2beornot2be", 20 | "ip_filter": "123.123.123.123", 21 | "due_at": "2013-01-23T23:59:00-07:00", 22 | "lock_at": null, 23 | "unlock_at": "2013-01-21T23:59:00-07:00", 24 | "published": true, 25 | "locked_for_user": false, 26 | "lock_info": { 27 | "asset_string": "quiz_5", 28 | "unlock_at": "2013-01-01T00:00:00-06:00", 29 | "lock_at": "2013-02-01T00:00:00-06:00", 30 | "context_module": { } 31 | }, 32 | "lock_explanation": "This quiz is locked until September 1 at 12:00am" 33 | } -------------------------------------------------------------------------------- /CanvasKit/Models/CKIService.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIService.m 3 | // CanvasKit 4 | // 5 | // Created by Miles Wright on 10/14/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIService.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | 12 | @implementation CKIService 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey 15 | { 16 | NSDictionary *keyPaths = @{ 17 | @"partnerID": @"partner_id", 18 | @"resourceDomain": @"resource_domain", 19 | @"rtmp": @"rtmp_domain" 20 | }; 21 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 22 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 23 | } 24 | 25 | + (NSValueTransformer *)domainJSONTransformer 26 | { 27 | return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; 28 | } 29 | 30 | + (NSValueTransformer *)resourceDomainJSONTransformer 31 | { 32 | return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; 33 | } 34 | 35 | + (NSValueTransformer *)rtmpJSONTransformer 36 | { 37 | return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/course.json: -------------------------------------------------------------------------------- 1 | { 2 | "sis_course_id": "2", 3 | "workflow_state": "available", 4 | "account_id": "1", 5 | "root_account_id": "1", 6 | "course_code": "iOS_101", 7 | "default_view": "wiki", 8 | "id": 1, 9 | "name": "Beginning iOS Development", 10 | "start_at": "2010-12-02T00:00:00-07:00", 11 | "end_at": "2010-14-02T00:00:00-07:00", 12 | "public_syllabus": true, 13 | "default_view": "feed", 14 | "syllabus_body": "

syllabus html goes here

", 15 | "needs_grading_count": 17, 16 | "storage_quota_mb": 500, 17 | "apply_assignment_group_weights": true, 18 | "permissions": {"create_discussion_topic": true}, 19 | "calendar": { 20 | "ics": "https://mobiledev.instructure.com/feeds/calendars/course_56093f00-e060-012d-6ee9-4040654c8f83.ics" 21 | }, 22 | "is_public": true, 23 | "public_description": "Come one, come all to InstructureCon 2012!", 24 | "storage_quota_mb": 5, 25 | "hide_final_grades": false, 26 | "license": "Creative Commons", 27 | "allow_student_assignment_edits": false, 28 | "allow_wiki_comments": false, 29 | "allow_student_forum_attachments": false, 30 | "open_enrollment": true, 31 | "self_enrollment": false, 32 | "restrict_enrollments_to_course_dates": false 33 | } -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/CKIMediaComment.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIMediaComment.m 3 | // Created by Jason Larsen on 5/8/14. 4 | // 5 | 6 | #import "CKIMediaComment.h" 7 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 8 | 9 | NSString * const CKIMediaCommentMediaTypeAudio = @"audio"; 10 | NSString * const CKIMediaCommentMediaTypeVideo = @"video"; 11 | 12 | @interface CKIMediaComment () 13 | 14 | @end 15 | 16 | @implementation CKIMediaComment 17 | 18 | + (NSDictionary *)JSONKeyPathsByPropertyKey 19 | { 20 | NSDictionary *keyPaths = @{ 21 | @"id": @"media_id", 22 | @"mediaID" : @"media_id", 23 | @"displayName" : @"display_name", 24 | @"contentType" : @"content-type", // watch the - ! 25 | @"mediaType" : @"media_type", 26 | @"url" : @"url" 27 | }; 28 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 29 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 30 | } 31 | 32 | + (NSValueTransformer *)urlJSONTransformer 33 | { 34 | return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; 35 | } 36 | 37 | // override the CKIModel version because mediaID is already a string 38 | + (NSValueTransformer *)idJSONTransformer { 39 | return nil; 40 | } 41 | 42 | @end -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CKAssignmentsTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKAssignmentsTableViewController.m 3 | // CanvasKit 2.0 Example 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CKAssignmentsTableViewController.h" 12 | 13 | @interface CKAssignmentsTableViewController () 14 | 15 | @end 16 | 17 | @implementation CKAssignmentsTableViewController 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | } 23 | 24 | #pragma mark - Table view data source 25 | 26 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 27 | { 28 | return 1; 29 | } 30 | 31 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 32 | { 33 | return [self.assignments count]; 34 | } 35 | 36 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 37 | { 38 | static NSString *CellIdentifier = @"AssignmentCell"; 39 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 40 | 41 | CKIAssignment *assignment = self.assignments[indexPath.row]; 42 | cell.textLabel.text = assignment.name; 43 | 44 | return cell; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKITab.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKITab.m 3 | // CanvasKit 4 | // 5 | // Created by rroberts on 9/17/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKITab.h" 10 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 11 | #import "CKICourse.h" 12 | 13 | @implementation CKITab 14 | @dynamic context; 15 | 16 | + (NSDictionary *)JSONKeyPathsByPropertyKey 17 | { 18 | NSDictionary *keyPaths = @{ 19 | @"htmlURL": @"html_url", 20 | @"label": @"label", 21 | @"type": @"type" 22 | }; 23 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 24 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 25 | } 26 | 27 | + (NSValueTransformer *)htmlURLJSONTransformer 28 | { 29 | return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; 30 | } 31 | 32 | + (NSValueTransformer *)urlJSONTransformer 33 | { 34 | return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; 35 | } 36 | 37 | + (NSValueTransformer *)idJSONTransformer 38 | { 39 | return nil; 40 | } 41 | 42 | - (NSString *)path 43 | { 44 | return [self.context.path stringByAppendingPathComponent:self.id]; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIActivityStreamAnnouncementItemTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamAnnouncementItemTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/17/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKIActivityStreamAnnouncementItemTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | let activityStreamAnnouncementItemDictionary = Helpers.loadJSONFixture("activity_stream_announcement_item") as NSDictionary? 26 | println("item = \(activityStreamAnnouncementItemDictionary)") 27 | let streamItem = CKIActivityStreamAnnouncementItem(fromJSONDictionary: activityStreamAnnouncementItemDictionary) 28 | 29 | let id: String = streamItem.announcementID 30 | println("id = \(id)") 31 | XCTAssertEqual(id, "1234", "Stream Announcement Item id was not parsed correctly") 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIOutcome.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIOutcome.m 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/20/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIOutcome.h" 10 | 11 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 12 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 13 | 14 | @implementation CKIOutcome 15 | 16 | + (NSDictionary *)JSONKeyPathsByPropertyKey 17 | { 18 | NSDictionary *keyPaths = @{ 19 | @"contextID": @"context_id", 20 | @"contextType": @"context_type", 21 | @"details": @"description", 22 | @"pointsPossible": @"points_possible", 23 | @"masteryPoints": @"mastery_points", 24 | }; 25 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 26 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 27 | } 28 | 29 | + (NSValueTransformer *)contextIDJSONTransformer 30 | { 31 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 32 | } 33 | 34 | - (NSString *)path 35 | { 36 | return [[self.context.path stringByAppendingPathComponent:@"outcomes"] stringByAppendingPathComponent:self.id]; 37 | } 38 | 39 | @end -------------------------------------------------------------------------------- /CanvasKit/Models/Rubric/CKIRubricCriterionRating.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubricCriterionRating.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/29/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | /** 12 | A rubric criterion rating is one of the pre-defined 13 | ratings that can be selected for assignemnts that are graded 14 | on a rubric. 15 | 16 | For example, a rubric criterion for "Grammar" might have 3 ratings, 17 | 5 points for "Perfect", 3 for "OK", and 1 for "Too many mistakes." 18 | 19 | In addition, some rubrics allow teachers to assign custom points 20 | when one of the pre-defined options is not fine-grained enough. In 21 | this case, they may choose to include a comment explaining the custom 22 | grade. 23 | */ 24 | @interface CKIRubricCriterionRating : CKIModel 25 | 26 | /** 27 | The points given to the student for the criteria when 28 | this rating is selected. 29 | */ 30 | @property (nonatomic) double points; 31 | 32 | /** 33 | A description for this rating, explaining the reasoning 34 | behind the points. 35 | */ 36 | @property (nonatomic, copy) NSString *ratingDescription; 37 | 38 | /** 39 | Graders can add a comment for the rating when they give 40 | a grade that was not on the rubric. 41 | */ 42 | @property (nonatomic, copy) NSString *comments; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /CanvasKit/Networking/Live Assessments/CKIClient+CKILiveAssessmentResult.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKILiveAssessmentResult.m 3 | // CanvasKit 4 | // 5 | // Created by Derrick Hathaway on 6/9/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKILiveAssessmentResult.h" 10 | #import "CKILiveAssessment.h" 11 | #import "CKILiveAssessmentResult.h" 12 | #import 13 | 14 | @implementation CKIClient (CKILiveAssessmentResult) 15 | 16 | - (RACSignal *)createResults:(NSArray *)results forLiveAssessment:(CKILiveAssessment *)assessment 17 | { 18 | NSString *path = [assessment.path stringByAppendingPathComponent:@"results"]; 19 | 20 | NSArray *json = [[NSValueTransformer mtl_JSONArrayTransformerWithModelClass:[CKILiveAssessmentResult class]] reverseTransformedValue:results]; 21 | 22 | json = [json.rac_sequence map:^id(NSDictionary *result) { 23 | NSMutableDictionary *updated = [result mutableCopy]; 24 | [updated removeObjectForKey:@"id"]; 25 | updated[@"links"] = @{@"user": [updated valueForKeyPath:@"links.user"]}; 26 | return updated; 27 | }].array; 28 | 29 | return [self createModelAtPath:path parameters:@{[CKILiveAssessmentResult keyForJSONAPIContent]: json} modelClass:[CKILiveAssessmentResult class] context:assessment]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIEnrollment.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // CKIEnrollment.h 4 | // CanvasKit 5 | // 6 | // Created by rroberts on 1/10/14. 7 | // Copyright (c) 2014 Instructure. All rights reserved. 8 | // 9 | 10 | #import "CKIModel.h" 11 | 12 | typedef NS_ENUM(NSUInteger, CKIEnrollmentType) { 13 | CKIEnrollmentTypeStudent, 14 | CKIEnrollmentTypeTeacher, 15 | CKIEnrollmentTypeTA, 16 | CKIEnrollmentTypeObserver, 17 | CKIEnrollmentTypeMember, 18 | CKIEnrollmentTypeDesigner, 19 | CKIEnrollmentTypeUnknown 20 | }; 21 | 22 | @interface CKIEnrollment : CKIModel 23 | 24 | @property (nonatomic) CKIEnrollmentType type; 25 | @property (nonatomic, strong) NSString *role; 26 | @property (nonatomic, strong) NSString *state; 27 | @property (nonatomic, strong) NSNumber *computedFinalScore; 28 | @property (nonatomic, strong) NSNumber *computedCurrentScore; 29 | @property (nonatomic, strong) NSString *computedFinalGrade; 30 | @property (nonatomic, strong) NSString *computedCurrentGrade; 31 | @property (nonatomic, strong) NSString *currentGradingPeriodID; 32 | @property (nonatomic, strong) NSNumber *currentGradingPeriodScore; 33 | @property (nonatomic, strong) NSString *currentGradingPeriodGrade; 34 | @property (nonatomic) BOOL multipleGradingPeriodsEnabled; 35 | @property (nonatomic, strong) NSString *sectionID; 36 | @property (nonatomic, readonly) BOOL isStudent; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIRubricTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubricTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/18/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKIRubricTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | 26 | let rubricDictionary = Helpers.loadJSONFixture("rubric") as NSDictionary 27 | let rubric = CKIRubric(fromJSONDictionary: rubricDictionary) 28 | 29 | //I don't think these tests are very useful because I don't think the rubric.h/.m class is necessary 30 | XCTAssertEqual(rubric.title!, "Made Up Title", "rubric id did not parse correctly") 31 | XCTAssertEqual(rubric.pointsPossible, 10.5, "rubric pointsPossible did not parse correctly") 32 | XCTAssertFalse(rubric.allowsFreeFormCriterionComments, "rubric allowsFreeFormCriterionComments did not parse correctly") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIConversationMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIConversationMessage.h 3 | // CanvasKit 4 | // 5 | // Created by derrick on 11/26/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @class CKIMediaComment, CKISubmission; 12 | 13 | @interface CKIConversationMessage : CKIModel 14 | 15 | /** 16 | the date that the message was created 17 | */ 18 | @property (nonatomic, copy) NSDate *createdAt; 19 | 20 | /** 21 | the body of the message (html) 22 | */ 23 | @property (nonatomic, copy) NSString *body; 24 | 25 | /** 26 | The id of the author 27 | */ 28 | @property (nonatomic, copy) NSString *authorID; 29 | 30 | /** 31 | an array of CKIConversationMessage objects that represent 32 | forwarded messages 33 | */ 34 | @property (nonatomic, copy) NSArray *forwardedMessages; 35 | 36 | /** 37 | an array of `CKIConversationMessageAttachment`s 38 | */ 39 | @property (nonatomic, copy) NSArray *attachments; 40 | 41 | /** 42 | Is this a system generated message i.e.: "Bob added Alice to the conversation" 43 | */ 44 | @property (nonatomic) BOOL generated; 45 | 46 | /** 47 | A CKIConversationMediaComment 48 | */ 49 | @property (nonatomic) CKIMediaComment *mediaComment; 50 | 51 | 52 | /** 53 | The submission that this conversation belongs to 54 | */ 55 | @property (nonatomic) CKISubmission *submission; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIConversationRecipient.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIConversationRecipient.m 3 | // CanvasKit 4 | // 5 | // Created by Ben Kraus on 12/2/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIConversationRecipient.h" 10 | #import "CKIConversationRecipient.h" 11 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 12 | 13 | @implementation CKIClient (CKIConversationRecipient) 14 | 15 | - (RACSignal *)fetchConversationRecipientsWithSearchString:(NSString *)search inContext:(NSString *)contextID 16 | { 17 | NSString *path = [[CKIRootContext.path stringByAppendingPathComponent:@"search"] stringByAppendingPathComponent:@"recipients"]; 18 | 19 | NSDictionary *params = @{@"search":[search stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]}; 20 | if (contextID) { 21 | params = [params dictionaryByAddingObjectsFromDictionary:@{ 22 | @"context": contextID, 23 | @"synthetic_contexts": @1 24 | }]; 25 | } 26 | 27 | return [self fetchResponseAtPath:path parameters:params modelClass:[CKIConversationRecipient class] context:CKIRootContext]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIGroup.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient.h" 10 | 11 | @class CKIGroup; 12 | @class CKIGroupCategory; 13 | @class CKICourse; 14 | @class RACSignal; 15 | 16 | @interface CKIClient (CKIGroup) 17 | 18 | - (RACSignal *)fetchGroup:(NSString *)groupID; 19 | 20 | - (RACSignal *)fetchGroupsForLocalUser; 21 | 22 | - (RACSignal *)fetchGroupsForAccount:(NSString *)accountID; 23 | 24 | - (RACSignal *)fetchGroup:(NSString *)groupID forContext:(id)context; 25 | 26 | - (RACSignal *)fetchGroupsForContext:(id )context; 27 | 28 | - (RACSignal *)fetchGroupsForGroupCategory:(CKIGroupCategory *)category; 29 | 30 | - (RACSignal *)fetchGroupUsersForContext:(id )context; 31 | 32 | - (RACSignal *)deleteGroup:(CKIGroup *)group; 33 | 34 | - (RACSignal *)createGroup:(CKIGroup *)group; 35 | 36 | - (RACSignal *)createGroup:(CKIGroup *)group category:(CKIGroupCategory *)category; 37 | 38 | - (RACSignal *)inviteUser:(NSString *)userEmail toGroup:(CKIGroup *)group; 39 | 40 | - (RACSignal *)createGroupMemebershipForUser:(NSString *)userID inGroup:(CKIGroup *)group; 41 | 42 | - (RACSignal *)removeGroupMemebershipForUser:(NSString *)userID inGroup:(CKIGroup *)group; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKITodoItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKITodoItem.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKITodoItem.h" 10 | #import "CKITodoItem.h" 11 | #import "CKICourse.h" 12 | #import "CKIAssignment.h" 13 | #import 14 | 15 | @implementation CKIClient (CKITodoItem) 16 | 17 | - (RACSignal *)fetchTodoItemsForCourse:(CKICourse *)course 18 | { 19 | NSString *path = [[course path] stringByAppendingPathComponent:@"todo"]; 20 | return [[self fetchResponseAtPath:path parameters:nil modelClass:[CKITodoItem class] context:course] map:^(NSArray *value) { 21 | for (CKITodoItem *item in value) { 22 | item.assignment.context = course; 23 | } 24 | return value; 25 | }]; 26 | 27 | } 28 | 29 | - (RACSignal *)fetchTodoItemsForCurrentUser 30 | { 31 | NSString *path = [CKIRootContext.path stringByAppendingPathComponent:@"users/self/todo"]; 32 | return [[self fetchResponseAtPath:path parameters:nil modelClass:[CKITodoItem class] context:nil] map:^(NSArray *value) { 33 | for (CKITodoItem *item in value) { 34 | item.assignment.context = [CKICourse modelWithID:item.assignment.courseID]; 35 | } 36 | return value; 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /CanvasKitTests/Models/CKIServiceSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIServiceSpec.m 3 | // CanvasKit 4 | // 5 | // Created by Miles Wright on 10/8/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Helpers.h" 11 | 12 | #import "CKIService.h" 13 | 14 | SPEC_BEGIN(CKIServiceSpec) 15 | 16 | describe(@"A service", ^{ 17 | 18 | context(@"when created from service.json", ^{ 19 | NSDictionary *json = loadJSONFixture(@"service"); 20 | CKIService *service = [CKIService modelFromJSONDictionary:json]; 21 | 22 | it(@"gets domain", ^{ 23 | NSURL *url = [NSURL URLWithString:@"kaltura.example.com"]; 24 | [[service.domain should] equal:url]; 25 | }); 26 | it(@"gets enabled", ^{ 27 | [[theValue(service.enabled) should] beTrue]; 28 | }); 29 | it(@"gets partner id", ^{ 30 | [[service.partnerID should] equal:@"123456"]; 31 | }); 32 | it(@"gets resource domain", ^{ 33 | NSURL *url = [NSURL URLWithString:@"cdn.kaltura.example.com"]; 34 | [[service.resourceDomain should] equal:url]; 35 | }); 36 | it(@"gets rmtp domain", ^{ 37 | NSURL *url = [NSURL URLWithString:@"rmtp.example.com"]; 38 | [[service.rmtpDomain should] equal:url]; 39 | }); 40 | }); 41 | }); 42 | 43 | SPEC_END -------------------------------------------------------------------------------- /CanvasKit/Models/CKIRubricAssessment.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubricAssessment.m 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 8/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIRubricAssessment.h" 10 | #import "CKIRubricCriterionRating.h" 11 | 12 | @implementation CKIRubricAssessment 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey 15 | { 16 | NSDictionary *keyPaths = @{ 17 | @"ratings": @"ratings", 18 | }; 19 | return keyPaths; 20 | } 21 | 22 | + (NSValueTransformer *)ratingsJSONTransformer 23 | { 24 | return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:[CKIRubricCriterionRating class]]; 25 | } 26 | 27 | - (NSDictionary *)parametersDictionary { 28 | NSMutableDictionary *params = [NSMutableDictionary dictionary]; 29 | [self.ratings enumerateObjectsUsingBlock:^(CKIRubricCriterionRating *rating, NSUInteger idx, BOOL *stop) { 30 | 31 | NSMutableDictionary *ratingInfo = [NSMutableDictionary new]; 32 | ratingInfo[@"points"] = [NSString stringWithFormat:@"%g", rating.points]; 33 | 34 | NSString *comments = rating.comments ? rating.comments : @""; 35 | ratingInfo[@"comments"] = comments; 36 | [params setObject:ratingInfo forKey:rating.id]; 37 | }]; 38 | 39 | return params; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /CanvasKit/Models/Rubric/CKIRubricCriterion.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIRubricCriterion.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/29/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CKIModel.h" 11 | 12 | @class CKIRubricCriterionRating; 13 | 14 | /** 15 | A rubric is made up of various criteria. 16 | 17 | For example, a criterion might be "Grammar" and have a score 18 | of 4 for a student. It may also have a list of pre-defined 19 | ratings the grader can use that were set up with the rubric. 20 | */ 21 | @interface CKIRubricCriterion : CKIModel 22 | 23 | /** 24 | Points scored on this criterion. 25 | */ 26 | @property (nonatomic) double points; 27 | 28 | /** 29 | Description of the criterion. 30 | */ 31 | @property (nonatomic, copy) NSString *criterionDescription; 32 | 33 | /** 34 | A more detailed description of the criterion. 35 | */ 36 | @property (nonatomic, copy) NSString *longDescription; 37 | 38 | /** 39 | Array of CKIRubricCriterionRating for this criterion. 40 | */ 41 | @property (nonatomic, copy) NSArray *ratings; 42 | 43 | /** 44 | The position of the Rubric Criterion 45 | */ 46 | @property (nonatomic) NSInteger position; 47 | 48 | /** 49 | The currently selected rating for this criterion, if any. 50 | */ 51 | @property (nonatomic, readonly) CKIRubricCriterionRating *selectedRating; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIISO8601DateMatcher.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIISO8601DateMatcher.m 3 | // CanvasKit 4 | // 5 | // Created by Miles Wright on 10/2/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIISO8601DateMatcher.h" 10 | #import "ISO8601DateFormatter.h" 11 | 12 | @interface CKIISO8601DateMatcher () 13 | 14 | @property (nonatomic, strong) id otherSubject; 15 | 16 | @end 17 | 18 | @implementation CKIISO8601DateMatcher 19 | 20 | #pragma mark Getting Matcher Strings 21 | 22 | + (NSArray *)matcherStrings 23 | { 24 | return @[@"equalISO8601String:"]; 25 | } 26 | 27 | #pragma mark Matching 28 | 29 | - (BOOL)evaluate 30 | { 31 | static ISO8601DateFormatter *formatter; 32 | static dispatch_once_t onceToken; 33 | dispatch_once(&onceToken, ^{ 34 | formatter = [ISO8601DateFormatter new]; 35 | }); 36 | 37 | NSDate *expectedDate = [formatter dateFromString:self.otherSubject]; 38 | 39 | return [self.subject isEqual:expectedDate]; 40 | } 41 | 42 | #pragma mark Getting Failure Messages 43 | 44 | - (NSString *)failureMessageForShould 45 | { 46 | return [NSString stringWithFormat:@"expected subject to be %@, value was %@", self.subject, self.otherSubject]; 47 | } 48 | 49 | #pragma mark Configuring Matchers 50 | 51 | - (void)equalISO8601String:(id)anObject 52 | { 53 | self.otherSubject = anObject; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPollChoice.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPollChoice.m 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/22/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIPollChoice.h" 10 | 11 | @implementation CKIClient (CKIPollChoice) 12 | 13 | - (RACSignal *)fetchPollChoicesForPoll:(CKIPoll *)poll 14 | { 15 | NSString *path = [poll.path stringByAppendingPathComponent:@"poll_choices"]; 16 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIPollChoice class] context:poll]; 17 | } 18 | 19 | - (RACSignal *)fetchPollChoiceWithId:(NSString *)pollChoiceId fromPoll:(CKIPoll *)poll 20 | { 21 | NSString *path = [[poll.path stringByAppendingPathComponent:@"poll_choices"] stringByAppendingPathComponent:pollChoiceId]; 22 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIPollChoice class] context:poll]; 23 | } 24 | 25 | - (RACSignal *)createPollChoice:(CKIPollChoice *)pollChoice forPoll:(CKIPoll *)poll 26 | { 27 | NSString *path = [poll.path stringByAppendingPathComponent:@"poll_choices"]; 28 | NSDictionary *parameters = @{@"poll_choices": @[@{@"text": pollChoice.text, @"is_correct": @(pollChoice.isCorrect), @"position": pollChoice.index}]}; 29 | return [self createModelAtPath:path parameters:parameters modelClass:[CKIPollChoice class] context:poll]; 30 | } 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /CanvasKitTests/Models/CKIActivityStreamDiscussionTopicItemSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamDiscussionTopicItemSpec.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/4/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Helpers.h" 11 | #import "CKIISO8601DateMatcher.h" 12 | 13 | #import "CKIActivityStreamDiscussionTopicItem.h" 14 | 15 | SPEC_BEGIN(CKIActivityStreamDiscussionTopicItemSpec) 16 | 17 | registerMatchers(@"CKI"); 18 | 19 | describe(@"A dicussion topic activity stream item", ^{ 20 | context(@"when created from json fixture", ^{ 21 | NSDictionary *json = loadJSONFixture(@"activity_stream_discussion_topic_item"); 22 | CKIActivityStreamDiscussionTopicItem *streamItem = [CKIActivityStreamDiscussionTopicItem modelFromJSONDictionary:json]; 23 | 24 | it(@"gets the total root discussion entries", ^{ 25 | [[theValue(streamItem.totalRootDiscussionEntries) should] equal:theValue(5)]; 26 | }); 27 | 28 | it(@"gets the boolean for require initial post", ^{ 29 | [[theValue(streamItem.requireInitialPost) should] equal:theValue(YES)]; 30 | }); 31 | 32 | it(@"gets gets the boolean for user has posted", ^{ 33 | [[theValue(streamItem.userHasPosted) should] equal:theValue(YES)]; 34 | }); 35 | }); 36 | }); 37 | 38 | SPEC_END 39 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIOutcomeGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIOutcomeGroup.h 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/20/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIModel.h" 10 | 11 | @interface CKIOutcomeGroup : CKIModel 12 | 13 | /** 14 | The title for the outcome group. 15 | */ 16 | @property (nonatomic, copy) NSString *title; 17 | 18 | /** 19 | The description for the outcome group. 20 | */ 21 | @property (nonatomic, copy) NSString *details; 22 | 23 | /** 24 | The context type of the outcome group. 25 | */ 26 | @property (nonatomic, copy) NSString *contextType; 27 | 28 | /** 29 | The context owning the outcome group. may be null for global outcome groups. Omitted in the abbreviated form 30 | */ 31 | @property (nonatomic, copy) NSString *contextID; 32 | 33 | /** 34 | The URL for fetching/updating the outcome group. should be treated as opaque 35 | */ 36 | @property (nonatomic, copy) NSString *url; 37 | 38 | /** 39 | The URL for listing/creating subgroups under the outcome group. 40 | */ 41 | @property (nonatomic, copy) NSString *subgroupsURL; 42 | 43 | /** 44 | The URL for listing/creating outcome links under the outcome group. 45 | */ 46 | @property (nonatomic, copy) NSString *outcomesURL; 47 | 48 | /** 49 | OutcomeGroup object representing the parent group of this outcome group, if any 50 | */ 51 | @property (nonatomic, copy) CKIOutcomeGroup *parent; 52 | 53 | @end -------------------------------------------------------------------------------- /Example/CanvasKit 2.0 Example/CanvasKit 2.0 Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | instructure.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKIOutcomeGroup.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIOutcomeGroup.m 3 | // CanvasKit 4 | // 5 | // Created by Brandon Pluim on 5/20/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIOutcomeGroup.h" 10 | 11 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 12 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 13 | 14 | @implementation CKIOutcomeGroup 15 | 16 | + (NSDictionary *)JSONKeyPathsByPropertyKey 17 | { 18 | NSDictionary *keyPaths = @{ 19 | @"contextID": @"context_id", 20 | @"contextType": @"context_type", 21 | @"subgroupsURL": @"subgroups_url", 22 | @"details": @"description", 23 | @"outcomesURL": @"outcomes_url", 24 | @"parent": @"parent_outcome_group", 25 | }; 26 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 27 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 28 | } 29 | 30 | + (NSValueTransformer *)contextIDJSONTransformer 31 | { 32 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 33 | } 34 | 35 | - (NSString *)path 36 | { 37 | return [[self.context.path stringByAppendingPathComponent:@"outcome_groups"] stringByAppendingPathComponent:self.id]; 38 | } 39 | 40 | @end -------------------------------------------------------------------------------- /CanvasKit/Models/CKIModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKIModel.h 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 8/22/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | @import Mantle; 10 | #import "CKIContext.h" 11 | 12 | @interface CKIModel : MTLModel 13 | 14 | + (NSString *)keyForJSONAPIContent; 15 | 16 | /** 17 | Creates an empty model with the given ID assumes the `CKIRootContext` 18 | */ 19 | + (instancetype)modelWithID:(NSString *)modelID; 20 | 21 | /** 22 | Creates an empty model with the given ID in the given context 23 | */ 24 | + (instancetype)modelWithID:(NSString *)modelID context:(id)context; 25 | 26 | /** 27 | The unique identifier assigned to this model. 28 | */ 29 | @property (nonatomic, copy) NSString *id; 30 | 31 | /** 32 | the base url for this model object 33 | */ 34 | @property (nonatomic) NSURL *baseURL; 35 | 36 | /** 37 | Checks to see if two models are equivalent based on their ID. 38 | 39 | @param object the object to compare 40 | 41 | @returns true if objects have same IDs, else false. 42 | */ 43 | - (BOOL)isEqual:(id)object; 44 | 45 | 46 | /** 47 | Convenience method for instantiating class from a JSON dictionary. 48 | */ 49 | + (instancetype)modelFromJSONDictionary:(NSDictionary *)dictionaryValue; 50 | 51 | /** 52 | Convenience method for turning model into JSON dictionary. 53 | */ 54 | - (NSDictionary *)JSONDictionary; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/todo_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "context_type": "Course", 3 | "course_id": 1, 4 | "group_id": 2, 5 | "type": "grading", 6 | "assignment": { 7 | "assignment_group_id": 1, 8 | "automatic_peer_reviews": false, 9 | "description": "

details dj

", 10 | "due_at": "2013-07-25T23:59:59-06:00", 11 | "grade_group_students_individually": false, 12 | "grading_type": "points", 13 | "group_category_id": null, 14 | "id": 1, 15 | "lock_at": null, 16 | "peer_reviews": false, 17 | "points_possible": 6, 18 | "position": 1, 19 | "unlock_at": null, 20 | "course_id": 1, 21 | "name": "Assignment 1", 22 | "submission_types": [ 23 | "online_text_entry", 24 | "online_url", 25 | "media_recording", 26 | "online_upload" 27 | ], 28 | "muted": false, 29 | "html_url": "https://mobiledev.instructure.com/courses/1111375/assignments/3493245", 30 | "needs_grading_count": 1, 31 | "locked_for_user": false 32 | }, 33 | "ignore": "https://mobiledev.instructure.com/api/v1/users/self/todo/assignment_3493245/grading?permanent=0", 34 | "ignore_permanently": "https://mobiledev.instructure.com/api/v1/users/self/todo/assignment_3493245/grading?permanent=1", 35 | "html_url": "https://mobiledev.instructure.com/courses/1111375/gradebook/speed_grader?assignment_id=3493245", 36 | "needs_grading_count": 1 37 | } -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIPoll.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIPoll.m 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 5/8/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKIClient+CKIPoll.h" 10 | @import ReactiveCocoa; 11 | 12 | @implementation CKIClient (CKIPoll) 13 | 14 | - (RACSignal *)fetchPollsForCurrentUser 15 | { 16 | NSString *path = [CKIRootContext.path stringByAppendingPathComponent:@"polls"]; 17 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIPoll class] context:CKIRootContext]; 18 | } 19 | 20 | - (RACSignal *)fetchPollWithID:(NSString *)pollID 21 | { 22 | NSString *path = [[CKIRootContext.path stringByAppendingPathComponent:@"polls"] stringByAppendingPathComponent:pollID]; 23 | 24 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIPoll class] context:CKIRootContext]; 25 | } 26 | 27 | - (RACSignal *)createPoll:(CKIPoll *)poll 28 | { 29 | NSString *path = [CKIRootContext.path stringByAppendingPathComponent:@"polls"]; 30 | NSDictionary *params = @{ 31 | @"polls": @[@{@"question": poll.question}] 32 | }; 33 | return [self createModelAtPath:path parameters:params modelClass:[CKIPoll class] context:CKIRootContext]; 34 | } 35 | 36 | - (RACSignal *)deletePoll:(CKIPoll *)poll 37 | { 38 | return [self deleteObjectAtPath:poll.path modelClass:[CKIPoll class] parameters:nil context:poll]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIServiceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIServiceTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Rick Roberts on 7/8/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKIServiceTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | 26 | let serviceDictionary = Helpers.loadJSONFixture("service") as NSDictionary 27 | let service = CKIService(fromJSONDictionary: serviceDictionary) 28 | 29 | XCTAssertEqual(service.domain!, NSURL(string: "kaltura.example.com")!, "service domain not parsed correctly") 30 | XCTAssert(service.enabled, "service enabled not parsed correctly") 31 | XCTAssertEqual(service.partnerID!, "123456", "service partner id not parsed correctly") 32 | XCTAssertEqual(service.resourceDomain!, NSURL(string: "cdn.kaltura.example.com")!, "service resource domain not parsed correctly") 33 | XCTAssertEqual(service.rtmp!, NSURL(string: "rtmp.example.com")!, "service rmtp domain not parsed correctly") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CanvasKitTests/Networking Tests/CKITodoItemNetworkingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKITodoItemNetworkingTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/29/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKITodoItemNetworkingTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testFetchTodoItemsForCourse() { 24 | let courseDictionary = Helpers.loadJSONFixture("course") as NSDictionary 25 | let course = CKICourse(fromJSONDictionary: courseDictionary) 26 | let client = MockCKIClient() 27 | 28 | client.fetchTodoItemsForCourse(course) 29 | XCTAssertEqual(client.capturedPath!, "/api/v1/courses/1/todo", "CKITodoItem returned API path for testFetchTodoItemsForCourse was incorrect") 30 | } 31 | 32 | func testFetchTodoItemsForCurrentUser() { 33 | let client = MockCKIClient() 34 | 35 | client.fetchTodoItemsForCurrentUser() 36 | XCTAssertEqual(client.capturedPath!, "/api/v1/users/self/todo", "CKITodoItem returned API path for testFetchTodoItemsForCurrentUser was incorrect") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIActivityStreamConversationItemTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamConversationItem.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/10/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKIActivityStreamConversationItemTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testJSONModelConversion() { 24 | let activityStreamConversationItemDictionary = Helpers.loadJSONFixture("activity_stream_conversation_item") as NSDictionary 25 | let streamConversationItem = CKIActivityStreamConversationItem(fromJSONDictionary: activityStreamConversationItemDictionary) 26 | 27 | XCTAssert(streamConversationItem.isPrivate, "Stream Conversation Item isPrivate was not parsed correctly") 28 | 29 | XCTAssertEqual(streamConversationItem.participantCount, UInt(3), "Stream Discussion Item participantCount was not parsed correctly") 30 | 31 | XCTAssertEqual(streamConversationItem.conversationID!, "1234", "Stream Discussion Item conversationID was not parsed correctly") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKISectionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKISectionTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/18/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CKISectionTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testJSONModelConversion() { 24 | let sectionDictionary = Helpers.loadJSONFixture("section") as NSDictionary 25 | let section = CKISection(fromJSONDictionary: sectionDictionary) 26 | 27 | XCTAssertEqual(section.id!, "1", "section id not parsed correctly") 28 | XCTAssertEqual(section.name!, "Section A", "section name not parsed correctly") 29 | XCTAssertEqual(section.courseID!, "7", "section courseID not parsed correctly") 30 | XCTAssertEqual(section.path!, "/api/v1/sections/1", "section path not parsed correctly") 31 | } 32 | 33 | func testPerformanceExample() { 34 | // This is an example of a performance test case. 35 | self.measureBlock() { 36 | // Put the code you want to measure the time of here. 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /CanvasKitTests/Fixtures/enrollment.json: -------------------------------------------------------------------------------- 1 | { 2 | "associated_user_id":null, 3 | "sis_course_id": "SHEL93921", 4 | "course_integration_id": "SHEL93921", 5 | "section_integration_id": "SHEL93921", 6 | "sis_import_id": 83, 7 | "root_account_id": 1, 8 | "sis_section_id": "SHEL93921", 9 | "course_id":24219, 10 | "course_section_id":31105, 11 | "created_at":"2013-08-28T16:32:33Z", 12 | "end_at":null, 13 | "id":20179095, 14 | "limit_privileges_to_course_section":false, 15 | "root_account_id":99298, 16 | "start_at":null, 17 | "type":"designer", 18 | "updated_at":"2013-08-28T16:42:51Z", 19 | "user_id":4976425, 20 | "enrollment_state":"active", 21 | "role":"designer", 22 | "updated_at": "2012-04-18T23:08:51Z", 23 | "start_at": "2012-04-18T23:08:51Z", 24 | "end_at": "2012-04-18T23:08:51Z", 25 | "last_activity_at":"2013-08-28T16:43:00Z", 26 | "total_activity_time":260, 27 | "html_url":"https://mobiledev.instructure.com/courses/24219/users/4976425", 28 | "user":{ 29 | "id":4976425, 30 | "name":"mwsuman+designer@gmail.com", 31 | "sortable_name":"mwsuman+designer@gmail.com", 32 | "short_name":"mwsuman+designer@gmail.com" 33 | }, 34 | "grades":{ 35 | "html_url":"https://mobiledev.instructure.com/courses/24219/grades/5060228" 36 | }, 37 | "computed_final_score": 10, 38 | "computed_current_score": 11, 39 | "computed_final_grade": "A-", 40 | "computed_current_grade": "B+" 41 | } -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKITermTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKITermTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/16/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKITermTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | let termDictionary = Helpers.loadJSONFixture("term") as NSDictionary 26 | let term = CKITerm(fromJSONDictionary: termDictionary) 27 | 28 | XCTAssertEqual(term.id!, "1", "term id was not parsed correctly") 29 | XCTAssertEqual(term.name!, "Spring 2014", "term name was not parsed correctly") 30 | 31 | let formatter = ISO8601DateFormatter() 32 | formatter.includeTime = true 33 | var date = formatter.dateFromString("2014-01-06T08:00:00-05:00") 34 | XCTAssertEqual(term.startAt!, date, "term startAt was not parsed correctly") 35 | 36 | date = formatter.dateFromString("2014-05-16T05:00:00-04:00") 37 | XCTAssertEqual(term.endAt!, date, "term endAt was not parsed correctly") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CanvasKit/Models/CKISubmissions/CKISubmissionComment.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKISubmissionComment.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 9/8/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKISubmissionComment.h" 10 | #import "CKIUser.h" 11 | #import "CKIMediaComment.h" 12 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 13 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 14 | 15 | @implementation CKISubmissionComment 16 | 17 | + (NSDictionary *)JSONKeyPathsByPropertyKey 18 | { 19 | NSDictionary *keyPaths = @{ 20 | @"createdAt": @"created_at", 21 | @"authorID": @"author_id", 22 | @"authorName": @"author_name", 23 | @"avatarPath" : @"avatar_path", 24 | @"comment" : @"comment", 25 | @"mediaComment" : @"media_comment", 26 | }; 27 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 28 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 29 | } 30 | 31 | + (NSValueTransformer *)createdAtJSONTransformer 32 | { 33 | return [NSValueTransformer valueTransformerForName:CKIDateTransformerName]; 34 | } 35 | 36 | + (NSValueTransformer *)authorIDJSONTransformer 37 | { 38 | return [NSValueTransformer valueTransformerForName:CKINumberStringTransformerName]; 39 | } 40 | 41 | + (NSValueTransformer *)mediaCommentJSONTransformer 42 | { 43 | return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[CKIMediaComment class]]; 44 | } 45 | 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKIActivityStreamSubmissionItemTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKIActivityStreamSubmissionItemTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/17/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class CKIActivityStreamSubmissionItemTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testJSONModelConversion() { 25 | let activityStreamSubmissionItemDictionary = Helpers.loadJSONFixture("activity_stream_submission_item") as NSDictionary 26 | let streamItem = CKIActivityStreamSubmissionItem(fromJSONDictionary: activityStreamSubmissionItemDictionary) 27 | 28 | //This is a special case in the API. The API for submissions, "Returns a Submission with its Course and Assignment data." 29 | //While this is passing it may not reflect the actual way this data is received 30 | XCTAssertEqual(streamItem.submissionID!, "1234", "Stream Submission Item id was not parsed correctly") 31 | XCTAssertEqual(streamItem.assignmentID!, "1234", "Stream Submission Item id was not parsed correctly") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CanvasKitTests/Model Tests/CKILiveAssessmentTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKILiveAssessmentTests.swift 3 | // CanvasKit 4 | // 5 | // Created by Nathan Lambson on 7/31/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | import CanvasKit 12 | 13 | class CKILiveAssessmentTests: XCTestCase { 14 | 15 | override func setUp() { 16 | super.setUp() 17 | // Put setup code here. This method is called before the invocation of each test method in the class. 18 | } 19 | 20 | override func tearDown() { 21 | // Put teardown code here. This method is called after the invocation of each test method in the class. 22 | super.tearDown() 23 | } 24 | 25 | func testJSONModelConversion() { 26 | let liveAssessmentDictionary = Helpers.loadJSONFixture("live_assessment") as NSDictionary 27 | var live: CKILiveAssessment? = nil 28 | let liveAssessment = CKILiveAssessment(fromJSONDictionary: liveAssessmentDictionary) 29 | 30 | XCTAssertEqual(liveAssessment.id!, "42", "LiveAssessment id did not parse correctly") 31 | XCTAssertEqual(liveAssessment.outcomeID!, "10", "LiveAssessment outcome id did not parse correctly") 32 | XCTAssertEqual(CKILiveAssessment.keyForJSONAPIContent()!, "assessments", "LiveAssessment keyForJSONAPIContent was not parsed correctly") 33 | XCTAssertEqual(liveAssessment.path!, "/api/v1/live_assessments/42", "LiveAssessment path did not parse correctly") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CanvasKit/Networking/CKIClient+CKIExternalTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKIClient+CKIExternalTool.m 3 | // CanvasKit 4 | // 5 | // Created by Jason Larsen on 11/11/13. 6 | // Copyright (c) 2013 Instructure. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CKIClient+CKIExternalTool.h" 12 | #import "CKIExternalTool.h" 13 | #import "CKICourse.h" 14 | 15 | @implementation CKIClient (CKIExternalTool) 16 | 17 | - (RACSignal *)fetchExternalToolsForCourse:(CKICourse *)course 18 | { 19 | NSString *path = [course.path stringByAppendingPathComponent:@"external_tools"]; 20 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIExternalTool class] context:course]; 21 | } 22 | 23 | - (RACSignal *)fetchSessionlessLaunchURLWithURL:(NSString *)url course:(CKICourse *)course 24 | { 25 | NSString *path = [course.path stringByAppendingPathComponent:@"external_tools/sessionless_launch"]; 26 | 27 | NSDictionary *params = @{@"url":url}; 28 | return [self fetchResponseAtPath:path parameters:params modelClass:[CKIExternalTool class] context:course]; 29 | } 30 | 31 | - (RACSignal *)fetchExternalToolForCourseWithExternalToolID:(NSString *)externalToolID course:(CKICourse *)course 32 | { 33 | NSString *path = [course.path stringByAppendingPathComponent:@"external_tools"]; 34 | path = [path stringByAppendingPathComponent:externalToolID]; 35 | 36 | return [self fetchResponseAtPath:path parameters:nil modelClass:[CKIExternalTool class] context:course]; 37 | } 38 | 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /CanvasKit/Models/Live Assessments/CKILiveAssessmentResult.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKILiveAssessmentResult.m 3 | // CanvasKit 4 | // 5 | // Created by Derrick Hathaway on 6/9/14. 6 | // Copyright (c) 2014 Instructure. All rights reserved. 7 | // 8 | 9 | #import "CKILiveAssessmentResult.h" 10 | #import "NSValueTransformer+CKIPredefinedTransformerAdditions.h" 11 | #import "NSDictionary+DictionaryByAddingObjectsFromDictionary.h" 12 | #import "CKILiveAssessment.h" 13 | 14 | @implementation CKILiveAssessmentResult 15 | 16 | + (NSString *)keyForJSONAPIContent 17 | { 18 | return @"results"; 19 | } 20 | 21 | + (NSDictionary *)JSONKeyPathsByPropertyKey 22 | { 23 | NSDictionary *keyPaths = @{ 24 | @"assessedAt": @"assessed_at", 25 | @"assessedUserID": @"links.user", 26 | @"assessorUserID": @"links.assessor", 27 | @"context": [NSNull null], 28 | }; 29 | 30 | NSDictionary *superPaths = [super JSONKeyPathsByPropertyKey]; 31 | return [superPaths dictionaryByAddingObjectsFromDictionary:keyPaths]; 32 | } 33 | 34 | - (NSString *)path 35 | { 36 | return [[self.context.path stringByAppendingPathComponent:@"results"] stringByAppendingPathComponent:self.id]; 37 | } 38 | 39 | + (NSValueTransformer *)idJSONTransformer 40 | { 41 | return [MTLValueTransformer reversibleTransformerWithBlock:^id(id value) { 42 | return value; 43 | }]; 44 | } 45 | 46 | + (NSValueTransformer *)assessedAtJSONTransformer 47 | { 48 | return [NSValueTransformer valueTransformerForName:CKIDateTransformerName]; 49 | } 50 | 51 | @end 52 | --------------------------------------------------------------------------------