├── _Pods.xcodeproj ├── Example ├── Tests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── Tests-Prefix.pch │ ├── Tests-Info.plist │ └── Tests.m ├── SnapchatKit │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── SKViewController.h │ ├── SKAppDelegate.h │ ├── SNTableViewController.h │ ├── SnapchatKit-Prefix.pch │ ├── main.m │ ├── SKViewController.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Main.storyboard │ ├── SNTableViewController.m │ ├── SKAppDelegate.m │ └── SnapchatKit-Info.plist ├── SnapchatKit.xcodeproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── SnapchatKit.xcworkspace │ └── contents.xcworkspacedata ├── SnapchatKit-OSX │ └── SnapchatKit-OSX │ │ ├── TBTimer.h │ │ └── TBTimer.m ├── Podfile └── Pods │ ├── Local Podspecs │ └── SnapchatKit.podspec.json │ └── Pods.xcodeproj │ └── xcshareddata │ └── xcschemes │ └── SnapchatKit.xcscheme ├── .github └── FUNDING.yml ├── Pod ├── Classes │ ├── Model │ │ ├── SKProtocolErrorPacket.h │ │ ├── SKConnectPacket.h │ │ ├── SKPingResponsePacket.h │ │ ├── SKChatOutputStream.h │ │ ├── SKChatInputStream.h │ │ ├── SKErrorPacket.h │ │ ├── SKFoundFriend.h │ │ ├── SKMessageStatePacket.h │ │ ├── SKConnectResponsePacket.h │ │ ├── SKUserStory.h │ │ ├── SKNearbyUser.h │ │ ├── SKSnapStatePacket.h │ │ ├── SKConversationMessageResponsePacket.h │ │ ├── SKChatRoom.h │ │ ├── SKProtocolErrorPacket.m │ │ ├── SKReleaseMessagePacket.h │ │ ├── SKPingResponsePacket.m │ │ ├── SKErrorPacket.m │ │ ├── SKSuggestedFriend.m │ │ ├── SKLocation.h │ │ ├── SKChatOutputStream.m │ │ ├── SKPresencePacket.h │ │ ├── SKSuggestedFriend.h │ │ ├── SKMessageStatePacket.m │ │ ├── SKTrophy.h │ │ ├── SKConversationMessagePacket.h │ │ ├── TBQueue.h │ │ ├── SKUserStory.m │ │ ├── SKChatMessagePacket.h │ │ ├── SKAddedFriend.h │ │ ├── SKNewConversation.h │ │ ├── SKStoryUpdater.h │ │ ├── SKConnectResponsePacket.m │ │ ├── SKReleaseMessagePacket.m │ │ ├── SKSnapStatePacket.m │ │ ├── SKStoryOptions.m │ │ ├── SKStoryOptions.h │ │ ├── SKSnapResponse.h │ │ ├── TBQueue.m │ │ ├── SKStoryNote.h │ │ ├── SKConversationMessagePacket.m │ │ ├── SKSimpleUser.h │ │ ├── SKConversationMessageResponsePacket.m │ │ ├── SKSharedStoryDescription.h │ │ ├── SKTrophyMetrics.h │ │ ├── SKStoryUpdater.m │ │ ├── SKChatMessagePacket.m │ │ ├── SKFoundFriend.m │ │ ├── SKNearbyUser.m │ │ ├── SKConnectPacket.m │ │ ├── SKFilter.h │ │ ├── SKSnapOptions.h │ │ ├── SKChatInputStream.m │ │ ├── SKSnapOptions.m │ │ ├── SKNewConversation.m │ │ ├── SKConversationState.h │ │ ├── SKTrophy.m │ │ ├── SKAddedFriend.m │ │ ├── SKUser.h │ │ ├── SKAvatar.h │ │ ├── SKCasperCache.h │ │ ├── SKPresencePacket.m │ │ ├── SKStoryNote.m │ │ ├── SKPacket.h │ │ ├── SKTrophyMetrics.m │ │ ├── SKSharedStoryDescription.m │ │ ├── SKLocation.m │ │ ├── SKCashTransaction.h │ │ ├── SKUser.m │ │ ├── SKConversationState.m │ │ ├── SKSnap.h │ │ ├── SKStoryCollection.h │ │ ├── SKSimpleUser.m │ │ ├── SKThing.h │ │ ├── SKSnapResponse.m │ │ ├── SKFilter.m │ │ ├── SKStoryCollection.m │ │ ├── SKMessage.h │ │ ├── SKSnap.m │ │ ├── SKStory.h │ │ ├── SKBlob.h │ │ └── SKStory.m │ ├── Networking │ │ ├── SKClient+Discover.h │ │ ├── SKClient+Discover.m │ │ ├── SKClient+Device.h │ │ ├── SKClient+Snaps.h │ │ ├── SKClient+Device.m │ │ └── SKClient+Stories.h │ ├── Categories │ │ ├── NSMutableURLRequest+Util.h │ │ ├── NSArray+SnapchatKit.h │ │ ├── NSDictionary+SnapchatKit.h │ │ ├── NSMutableURLRequest+Util.m │ │ ├── NSArray+SnapchatKit.m │ │ ├── NSData+SnapchatKit.h │ │ ├── NSString+SnapchatKit.h │ │ └── NSDictionary+SnapchatKit.m │ └── SnapchatKit.h └── Dependencies │ ├── protobuf │ ├── RingBuffer.h │ ├── TextFormat.h │ ├── MutableExtensionRegistry.h │ ├── AbstractMessageBuilder.h │ ├── Bootstrap.h │ ├── WireFormat.m │ ├── GeneratedMessage.m │ ├── GeneratedMessageBuilder.h │ ├── MutableField.h │ ├── ForwardDeclarations.h │ ├── AbstractMessage.h │ ├── ProtocolBuffers.h │ ├── UnknownFieldSet.h │ ├── ExtensionRegistry.m │ ├── WireFormat.h │ ├── ExtensionField.h │ ├── Field.h │ ├── GeneratedMessage.h │ ├── MutableExtensionRegistry.m │ ├── UnknownFieldSetBuilder.h │ ├── ConcreteExtensionField.h │ ├── RingBuffer.m │ ├── Message.h │ ├── ExtendableMessageBuilder.h │ ├── GeneratedMessageBuilder.m │ ├── AbstractMessage.m │ ├── ExtensionRegistry.h │ ├── ExtendableMessage.h │ └── MutableField.m │ ├── minizip │ └── mztools.h │ └── SSZipArchive.h ├── SnapchatKit.podspec ├── .gitignore └── LICENSE /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [NSExceptional] 4 | -------------------------------------------------------------------------------- /Example/SnapchatKit/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/SnapchatKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SKViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKViewController.h 3 | // SnapchatKit 4 | // 5 | // Created by ThePantsThief on 07/29/2015. 6 | // Copyright (c) 2015 ThePantsThief. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface SKViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKProtocolErrorPacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKProtocolErrorPacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKPacket.h" 10 | 11 | 12 | @interface SKProtocolErrorPacket : SKPacket 13 | 14 | @property (nonatomic, readonly) NSString *message; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConnectPacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKConnectPacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKPacket.h" 10 | 11 | 12 | @interface SKConnectPacket : SKPacket 13 | 14 | + (instancetype)withUsername:(NSString *)username auth:(NSDictionary *)auth; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKPingResponsePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKPingResponsePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKPacket.h" 10 | 11 | 12 | @interface SKPingResponsePacket : SKPacket 13 | 14 | @property (nonatomic, readonly) NSString *pingIdentifier; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Pod/Classes/Networking/SKClient+Discover.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKClient+Discover.h 3 | // SnapchatKit-OSX-Demo 4 | // 5 | // Created by Tanner Bennett on 7/10/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKClient.h" 10 | 11 | @interface SKClient (Discover) 12 | 13 | 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKChatOutputStream.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKChatOutputStream.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import 10 | #import "SKPacket.h" 11 | 12 | 13 | @interface NSOutputStream (SKChatOutputStream) 14 | 15 | - (void)sendPacket:(SKPacket *)packet; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Pod/Classes/Networking/SKClient+Discover.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKClient+Discover.m 3 | // SnapchatKit-OSX-Demo 4 | // 5 | // Created by Tanner Bennett on 7/10/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKClient+Discover.h" 10 | 11 | @implementation SKClient (Discover) 12 | 13 | 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKChatInputStream.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKChatInputStream.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import 10 | #import "SKPacket.h" 11 | 12 | @interface NSInputStream (SKChatInputStream) 13 | 14 | - (SKPacket *)recievePacket; 15 | - (NSData *)readData; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKErrorPacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKErrorPacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKPacket.h" 10 | 11 | 12 | @interface SKErrorPacket : SKPacket 13 | 14 | @property (nonatomic, readonly) NSString *errorIdentifier; 15 | @property (nonatomic, readonly) NSString *message; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SKAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKAppDelegate.h 3 | // SnapchatKit 4 | // 5 | // Created by ThePantsThief on 07/29/2015. 6 | // Copyright (c) 2015 ThePantsThief. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface SKAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSMutableURLRequest+Util.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableURLRequest+Util.h 3 | // Pods 4 | // 5 | // Created by Tanner on 2/21/16. 6 | // 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface NSMutableURLRequest (Util) 13 | 14 | + (instancetype)POST:(NSString *)url body:(NSDictionary *)body headers:(NSDictionary *)headers; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SNTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SNTableViewController.h 3 | // SnapchatKit-iOS-Demo 4 | // 5 | // Created by Tanner on 7/11/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SNTableViewController : UITableViewController 12 | 13 | @property (nonatomic) NSArray *dataSource; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/SnapchatKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SnapchatKit-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 UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/SnapchatKit/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SnapchatKit 4 | // 5 | // Created by ThePantsThief on 07/29/2015. 6 | // Copyright (c) 2015 ThePantsThief. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "SKAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SKAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Example/SnapchatKit-OSX/SnapchatKit-OSX/TBTimer.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBTimeInterval.h 3 | // BU Eats 4 | // 5 | // Created by Tanner on 4/24/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TBTimer : NSObject 12 | 13 | + (void)startTimer; 14 | + (CGFloat)lap; 15 | 16 | @property (nonatomic, readonly) NSDate *startTime; 17 | @property (nonatomic, readonly) NSDate *endTime; 18 | 19 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/SKFoundFriend.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKFoundFriend.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | @interface SKFoundFriend : SKThing 12 | 13 | @property (nonatomic, readonly) NSString *displayName; 14 | @property (nonatomic, readonly) NSString *username; 15 | @property (nonatomic, readonly) BOOL isPrivate; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKMessageStatePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKMessageStatePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKConversationMessagePacket.h" 10 | 11 | 12 | @interface SKMessageStatePacket : SKConversationMessagePacket 13 | 14 | @property (nonatomic, readonly) NSString *chatMessageIdentifier; 15 | @property (nonatomic, readonly) NSString *state; 16 | @property (nonatomic, readonly) NSInteger version; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConnectResponsePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKConnectResponsePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 3/25/16. 6 | // 7 | // 8 | 9 | #import "SKPacket.h" 10 | 11 | @interface SKConnectResponsePacket : SKPacket 12 | 13 | @property (nonatomic, readonly) BOOL successful; 14 | @property (nonatomic, readonly) NSString *identifier; 15 | @property (nonatomic, readonly) NSString *failureReason; 16 | @property (nonatomic, readonly) NSString *alternateServer; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKUserStory.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKUserStory.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKStory.h" 10 | 11 | @interface SKUserStory : SKStory 12 | 13 | @property (nonatomic, readonly) NSUInteger screenshotCount; 14 | @property (nonatomic, readonly) NSUInteger viewCount; 15 | 16 | /** Array of SKStoryNote objects. */ 17 | @property (nonatomic, readonly) NSArray *notes; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKNearbyUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKNearbyUser.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 7/3/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SKThing.h" 11 | 12 | /** Passed to the callback of \c -[SKClient findFriendsNear:accuracy:pollDurationSoFar:completion: */ 13 | @interface SKNearbyUser : SKThing 14 | 15 | @property (nonatomic, readonly) NSString *username; 16 | @property (nonatomic, readonly) NSString *identifier; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnapStatePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnapStatePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKConversationMessagePacket.h" 10 | 11 | 12 | @interface SKSnapStatePacket : SKConversationMessagePacket 13 | 14 | @property (nonatomic, readonly) NSString *snapIdentifier; 15 | @property (nonatomic, readonly) NSInteger screenshotCount; 16 | @property (nonatomic, readonly) BOOL replayed; 17 | @property (nonatomic, readonly) BOOL opened; 18 | @property (nonatomic, readonly) NSDate *timestamp; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConversationMessageResponsePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKConversationMessageResponsePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKPacket.h" 10 | 11 | @interface SKConversationMessageResponsePacket : SKPacket 12 | 13 | @property (nonatomic, readonly) NSString *ACKIdentifier; 14 | @property (nonatomic, readonly) NSString *conversationIdentifier; 15 | @property (nonatomic, readonly) NSString *failureReason; 16 | @property (nonatomic, readonly) BOOL successful; 17 | @property (nonatomic, readonly) NSDate *timestamp; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSArray+SnapchatKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+SnapchatKit.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/22/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSArray (JSON) 12 | 13 | /// Will never return nil. 14 | @property (nonatomic, readonly) NSString *JSONString; 15 | /// Will never return nil. 16 | @property (nonatomic, readonly) NSArray *dictionaryValues; 17 | 18 | @end 19 | 20 | 21 | @interface NSArray (REST) 22 | @property (nonatomic, readonly) NSString *recipientsString; 23 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/SKChatRoom.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKChatRoom.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import 10 | #import "SKConversation.h" 11 | 12 | #define VALIDATE_CERTIFICATES 1 13 | 14 | 15 | @interface SKChatRoom : NSObject 16 | 17 | /// @param gatewayAuth See SKSession.messagingGatewayAuth 18 | + (instancetype)chatRoomForConversation:(SKConversation *)convo gatewayAuth:(NSDictionary *)gatewayAuth server:(NSString *)server; 19 | 20 | - (void)enterRoom; 21 | - (void)leaveRoom; 22 | 23 | @property (nonatomic) BOOL sendPresence; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKProtocolErrorPacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKProtocolErrorPacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKProtocolErrorPacket.h" 10 | 11 | 12 | @implementation SKProtocolErrorPacket 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | return [@{@"message": @"message"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 16 | } 17 | 18 | - (NSString *)description { 19 | return [NSString stringWithFormat:@"<%@ message=%@>", 20 | NSStringFromClass(self.class), self.message]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKReleaseMessagePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKReleaseMessagePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 3/25/16. 6 | // 7 | // 8 | 9 | #import "SKConversationMessagePacket.h" 10 | 11 | 12 | @interface SKReleaseMessagePacket : SKConversationMessagePacket 13 | 14 | @property (nonatomic, readonly) NSDictionary *knownChatSequenceNumbers; 15 | @property (nonatomic, readonly) NSDictionary *knownRecievedSnapsTimestamps; 16 | @property (nonatomic, readonly) NSString *releaseType; 17 | @property (nonatomic, readonly) NSDate *timestamp; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKPingResponsePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKPingResponsePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKPingResponsePacket.h" 10 | 11 | 12 | @implementation SKPingResponsePacket 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | return [@{@"pingIdentifier": @"ping_id"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 16 | } 17 | 18 | - (NSString *)description { 19 | return [NSString stringWithFormat:@"<%@ id=%@>", 20 | NSStringFromClass(self.class), self.pingIdentifier]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Pod/Classes/Networking/SKClient+Device.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKClient+Device.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKClient.h" 10 | 11 | @interface SKClient (Device) 12 | 13 | /** Sends the "app did open" event to Snapchat. 14 | @param completion Takes an error, if any. */ 15 | - (void)sendDidOpenAppEvent:(ErrorBlock)completion; 16 | /** Sends the "app did close" event to Snapchat. 17 | @param completion Takes an error, if any. */ 18 | - (void)sendDidCloseAppEvent:(ErrorBlock)completion; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKErrorPacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKErrorPacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKErrorPacket.h" 10 | 11 | 12 | @implementation SKErrorPacket 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | return [@{@"errorIdentifier": @"error_id", 16 | @"message": @"message"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 17 | } 18 | 19 | - (NSString *)description { 20 | return [NSString stringWithFormat:@"<%@ message=%@>", 21 | NSStringFromClass(self.class), self.message]; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSuggestedFriend.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKSuggestedFriend.m 3 | // Pods 4 | // 5 | // Created by Tanner on 12/23/15. 6 | // 7 | // 8 | 9 | #import "SKSuggestedFriend.h" 10 | 11 | @implementation SKSuggestedFriend 12 | 13 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 14 | return @{@"username": @"name", 15 | @"displayName": @"display", 16 | @"identifier": @"id", 17 | @"isHidden": @"is_hidden", 18 | @"isNewSnapchatter": @"is_new_snapchatter", 19 | @"suggestReason": @"suggest_reason", 20 | @"suggestReasonDisplay": @"suggest_reason_display"}; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/RingBuffer.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @interface RingBuffer : NSObject { 4 | NSMutableData *buffer; 5 | SInt32 position; 6 | SInt32 tail; 7 | } 8 | @property (nonatomic, readonly) UInt32 freeSpace; 9 | 10 | - (instancetype)initWithData:(NSMutableData*)data; 11 | 12 | // Returns false if there is not enough free space in buffer 13 | - (BOOL)appendByte:(uint8_t)byte; 14 | 15 | // Returns number of bytes written 16 | - (SInt32)appendData:(const NSData*)value offset:(SInt32)offset length:(SInt32)length; 17 | 18 | // Returns number of bytes written 19 | - (SInt32)flushToOutputStream:(NSOutputStream*)stream; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKLocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKLocation.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | @interface SKLocation : SKThing 12 | 13 | /** An array of \c SKFilter objects. */ 14 | @property (nonatomic, readonly) NSArray *filters; 15 | /** Undocumented */ 16 | @property (nonatomic, readonly) NSDictionary *weather; 17 | /** Undocumented */ 18 | @property (nonatomic, readonly) NSArray *ourStoryAuths; 19 | /** Undocumented */ 20 | @property (nonatomic, readonly) NSArray *preCacheGeofilters; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKChatOutputStream.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKChatOutputStream.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKChatOutputStream.h" 10 | #import "NSDictionary+SnapchatKit.h" 11 | 12 | 13 | @implementation NSOutputStream (SKChatOutputStream) 14 | 15 | - (void)sendPacket:(SKPacket *)packet { 16 | NSLog(@"Sent:\n%@\n", packet); 17 | NSData *json = [packet.json.JSONString dataUsingEncoding:NSUTF8StringEncoding]; 18 | int len = json.length; 19 | len = NSSwapInt(len); 20 | 21 | [self write:&len maxLength:sizeof(int)]; 22 | [self write:json.bytes maxLength:json.length]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SKViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKViewController.m 3 | // SnapchatKit 4 | // 5 | // Created by ThePantsThief on 07/29/2015. 6 | // Copyright (c) 2015 ThePantsThief. All rights reserved. 7 | // 8 | 9 | #import "SKViewController.h" 10 | 11 | @interface SKViewController () 12 | 13 | @end 14 | 15 | @implementation SKViewController 16 | 17 | - (void)viewDidLoad 18 | { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view, typically from a nib. 21 | } 22 | 23 | - (void)didReceiveMemoryWarning 24 | { 25 | [super didReceiveMemoryWarning]; 26 | // Dispose of any resources that can be recreated. 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKPresencePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKPresencePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKConversationMessagePacket.h" 10 | 11 | 12 | @interface SKPresencePacket : SKConversationMessagePacket 13 | 14 | + (instancetype)presences:(NSDictionary *)presences video:(BOOL)video to:(NSArray *)to from:(NSString *)from auth:(NSString *)auth; 15 | 16 | @property (nonatomic, readonly) NSDictionary *hereAuth; 17 | @property (nonatomic, readonly) NSDictionary *presences; 18 | @property (nonatomic, readonly) BOOL receivingVideo; 19 | @property (nonatomic, readonly) BOOL supportsHere; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSuggestedFriend.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKSuggestedFriend.h 3 | // Pods 4 | // 5 | // Created by Tanner on 12/23/15. 6 | // 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | @interface SKSuggestedFriend : SKThing 12 | 13 | @property (nonatomic, readonly) NSString *username; 14 | @property (nonatomic, readonly) NSString *displayName; 15 | @property (nonatomic, readonly) NSString *identifier; 16 | @property (nonatomic, readonly) BOOL isHidden; 17 | @property (nonatomic, readonly) BOOL isNewSnapchatter; 18 | /// ie, "new_contact" 19 | @property (nonatomic, readonly) NSString *suggestReason; 20 | /// ie, "New Contact" 21 | @property (nonatomic, readonly) NSString *suggestReasonDisplay; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | 4 | workspace 'SnapchatKit' 5 | xcodeproj 'SnapchatKit-OSX/SnapchatKit-OSX.xcodeproj' 6 | xcodeproj 'SnapchatKit.xcodeproj' 7 | 8 | target 'SnapchatKit_Example', :exclusive => true do 9 | platform :ios, '9.0' 10 | link_with 'SnapchatKit_Example' 11 | 12 | pod "SnapchatKit", :path => "../" 13 | end 14 | 15 | target 'SnapchatKit-OSX', :exclusive => true do 16 | xcodeproj 'SnapchatKit-OSX/SnapchatKit-OSX.xcodeproj' 17 | platform :osx, '10.8' 18 | link_with 'SnapchatKit-OSX' 19 | 20 | pod 'SnapchatKit', :path => '../' 21 | end 22 | 23 | target 'SnapchatKit_Tests', :exclusive => true do 24 | pod 'SnapchatKit', :path => '../' 25 | end 26 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKMessageStatePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKMessageStatePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKMessageStatePacket.h" 10 | 11 | 12 | @implementation SKMessageStatePacket 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | return [@{@"chatMessageIdentifier": @"chat_message_id", 16 | @"state": @"state", 17 | @"version": @"version"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 18 | } 19 | 20 | - (NSString *)description { 21 | return [NSString stringWithFormat:@"<%@ id=%@, version=%@>", 22 | NSStringFromClass(self.class), self.chatMessageIdentifier, @(self.version)]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKTrophy.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKTrophy.h 3 | // Pods 4 | // 5 | // Created by Tanner on 12/23/15. 6 | // 7 | // 8 | 9 | #import "SKThing.h" 10 | @class SKTrophyStage; 11 | 12 | 13 | @interface SKTrophy : SKThing 14 | 15 | @property (nonatomic, readonly) NSString *label; 16 | @property (nonatomic, readonly) NSString *unicode; 17 | @property (nonatomic, readonly) NSArray *stages; 18 | 19 | @end 20 | 21 | 22 | 23 | @interface SKTrophyStage : SKThing 24 | 25 | /// ie "CURRENT" or "UNACHIEVED" 26 | @property (nonatomic, readonly) NSString *status; 27 | @property (nonatomic, readonly) NSDate *achievedOn; 28 | 29 | @property (nonatomic, readonly) NSString *label; 30 | @property (nonatomic, readonly) NSString *unicode; 31 | 32 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConversationMessagePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKConversationMessagePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 3/25/16. 6 | // 7 | // 8 | 9 | #import "SKPacket.h" 10 | 11 | @interface SKConversationMessagePacket : SKPacket 12 | 13 | /// mac, payload 14 | @property (nonatomic, readonly) NSDictionary *auth; 15 | @property (nonatomic, readonly) NSInteger connSequenceNumber; 16 | @property (nonatomic, readonly) NSString *header_conversationIdentifier; 17 | @property (nonatomic, readonly) NSString *from; 18 | @property (nonatomic, readonly) NSArray *to; 19 | @property (nonatomic, readonly) BOOL retried; 20 | 21 | @property (nonatomic, readonly) BOOL canSendOverHTTP; 22 | @property (nonatomic, readonly) BOOL needsACK; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Pod/Classes/Model/TBQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBQueue.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface TBQueue<__covariant ObjectType> : NSObject { 13 | @private 14 | NSMutableArray *_list; 15 | } 16 | 17 | /// Adds obj to the end of the queue. 18 | - (void)enqueue:(nonnull ObjectType)obj; 19 | /// Dequeues and returns the fist object in the queue, reutrns \c nil if empty. 20 | - (nullable ObjectType)take; 21 | /// Empties the queue. 22 | - (void)clear; 23 | 24 | @property (nonatomic, readonly, nullable) ObjectType front; 25 | @property (nonatomic, readonly) NSUInteger count; 26 | @property (nonatomic, readonly) BOOL isEmpty; 27 | 28 | @end 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Example/Tests/Tests-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 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKUserStory.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKUserStory.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKUserStory.h" 10 | #import "SKStoryNote.h" 11 | 12 | @implementation SKUserStory 13 | 14 | #pragma mark - Mantle 15 | 16 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 17 | return [@{@"screenshotCount": @"story_extras.screenshot_count", 18 | @"viewCount": @"story_extras.view_count", 19 | @"notes": @"story_notes"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 20 | } 21 | 22 | + (NSValueTransformer *)notesJSONTransformer { return [self sk_modelArrayTransformerForClass:[SKStoryNote class]]; } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SnapchatKitTests.m 3 | // SnapchatKitTests 4 | // 5 | // Created by ThePantsThief on 07/29/2015. 6 | // Copyright (c) 2015 ThePantsThief. All rights reserved. 7 | // 8 | 9 | @import XCTest; 10 | 11 | @interface Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Tests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKChatMessagePacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKChatMessagePacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/6/16. 6 | // 7 | // 8 | 9 | #import "SKConversationMessagePacket.h" 10 | 11 | 12 | @interface SKChatMessagePacket : SKConversationMessagePacket 13 | 14 | @property (nonatomic, readonly) NSString *text; 15 | @property (nonatomic, readonly) NSDictionary *media; 16 | @property (nonatomic, readonly) NSString *messageType; 17 | @property (nonatomic, readonly) NSArray *attributes; 18 | 19 | @property (nonatomic, readonly) NSString *chatMessageIdentifier; 20 | @property (nonatomic, readonly) NSDictionary *state; 21 | @property (nonatomic, readonly) NSInteger sequenceNumber; 22 | @property (nonatomic, readonly) NSDate *timestamp; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKAddedFriend.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKAddedFriend.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKSimpleUser.h" 10 | 11 | /** Appears in the \c addedFriends property of \c SKSession. */ 12 | @interface SKAddedFriend : SKSimpleUser 13 | 14 | /** ie "Added you back" or "In my contacts - username" */ 15 | @property (nonatomic, readonly) NSString *addSource; 16 | /** How they were added. */ 17 | @property (nonatomic, readonly) SKAddSource addSourceType; 18 | /** When the request was sent. */ 19 | @property (nonatomic, readonly) NSDate *timestamp; 20 | /** The number of pending snaps you have from this user. */ 21 | @property (nonatomic, readonly) NSUInteger pendingSnaps; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKNewConversation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKNewConversation.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 7/11/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | /** Used internally. */ 12 | @interface SKNewConversation : NSObject 13 | 14 | + (instancetype)newConvoWithAuth:(NSDictionary *)macAndPayload withSender:(NSString *)sender otherUser:(NSString *)recipient; 15 | 16 | @property (nonatomic, readonly) NSString *identifier; 17 | @property (nonatomic, readonly) NSString *recipient; 18 | 19 | @property (nonatomic, readonly) NSString *mac; 20 | @property (nonatomic, readonly) NSString *payload; 21 | @property (nonatomic, readonly) NSDictionary *messagingAuth; 22 | @property (nonatomic, readonly) NSDictionary *state; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryUpdater.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/16/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | @class SKStory; 11 | 12 | /** The purpose of this class is to minimize error with the \c -markStoriesViewed: method in \c SKClient+Stories.h. */ 13 | @interface SKStoryUpdater : NSObject 14 | 15 | + (instancetype)viewedStory:(SKStory *)story at:(NSDate *)date screenshots:(NSUInteger)sscount; 16 | 17 | /** Used internally. */ 18 | @property (nonatomic, readonly) NSString *storyID; 19 | /** Used internally. */ 20 | @property (nonatomic, readonly) NSString *timestamp; 21 | /** Used internally. */ 22 | @property (nonatomic, readonly) NSUInteger screenshotCount; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Pod/Dependencies/minizip/mztools.h: -------------------------------------------------------------------------------- 1 | /* 2 | Additional tools for Minizip 3 | Code: Xavier Roche '2004 4 | License: Same as ZLIB (www.gzip.org) 5 | */ 6 | 7 | #ifndef _zip_tools_H 8 | #define _zip_tools_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #ifndef _ZLIB_H 15 | #include "zlib.h" 16 | #endif 17 | 18 | #include "unzip.h" 19 | 20 | /* Repair a ZIP file (missing central directory) 21 | file: file to recover 22 | fileOut: output file after recovery 23 | fileOutTmp: temporary file name used for recovery 24 | */ 25 | extern int ZEXPORT unzRepair(const char* file, 26 | const char* fileOut, 27 | const char* fileOutTmp, 28 | uLong* nRecovered, 29 | uLong* bytesRecovered); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConnectResponsePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKConnectResponsePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 3/25/16. 6 | // 7 | // 8 | 9 | #import "SKConnectResponsePacket.h" 10 | 11 | @implementation SKConnectResponsePacket 12 | 13 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 14 | return [@{@"successful": @"success", 15 | @"identifier": @"id", 16 | @"failureReason": @"failure_reason", 17 | @"alternateServer": @"alternative_server"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 18 | } 19 | 20 | - (NSString *)description { 21 | return [NSString stringWithFormat:@"<%@ successful=%@, failure=%@, alt server=%@>", 22 | NSStringFromClass(self.class), @(self.successful), self.failureReason, self.alternateServer]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /SnapchatKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "SnapchatKit" 3 | s.version = "0.6.1" 4 | s.summary = "An Objective-C implementation of the unofficial Snapchat API." 5 | s.homepage = "https://github.com/NSExceptional/SnapchatKit" 6 | s.license = 'MIT' 7 | s.author = { "ThePantsThief" => "tannerbennett@me.com" } 8 | s.source = { :git => "https://github.com/NSExceptional/SnapchatKit.git", :tag => s.version.to_s } 9 | 10 | s.requires_arc = true 11 | s.ios.deployment_target = '7.0' 12 | s.osx.deployment_target = '10.8' 13 | 14 | s.source_files = 'Pod/Classes/*', 'Pod/Classes/**/*', 'Pod/Dependencies/*', 'Pod/Dependencies/**/*' 15 | # s.dependency 'AFNetworking', '~> 2.5' 16 | # s.dependency 'SSZipArchive' 17 | s.dependency 'CocoaAsyncSocket' 18 | s.dependency 'Mantle', '~> 2.0' 19 | s.library = 'z' 20 | end 21 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKReleaseMessagePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKReleaseMessagePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 3/25/16. 6 | // 7 | // 8 | 9 | #import "SKReleaseMessagePacket.h" 10 | 11 | 12 | @implementation SKReleaseMessagePacket 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | return [@{@"knownChatSequenceNumbers": @"known_chat_sequence_numbers", 16 | @"knownRecievedSnapsTimestamps": @"known_received_snaps_ts", 17 | @"releaseType": @"release_type", 18 | @"timestamp": @"timestamp"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 19 | } 20 | 21 | MTLTransformPropertyDate(timestamp) 22 | 23 | - (NSString *)description { 24 | return [NSString stringWithFormat:@"<%@ type=%@, date=%@>", 25 | NSStringFromClass(self.class), self.releaseType, self.timestamp]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnapStatePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnapStatePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKSnapStatePacket.h" 10 | 11 | 12 | @implementation SKSnapStatePacket 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | return [@{@"snapIdentifier": @"snap_id", 16 | @"screenshotCount": @"screenshot_count", 17 | @"replayed": @"replayed", 18 | @"opened": @"viewed", 19 | @"timestamp": @"timestamp"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 20 | } 21 | 22 | MTLTransformPropertyDate(timestamp) 23 | 24 | - (NSString *)description { 25 | return [NSString stringWithFormat:@"<%@ ss count=%@, opened=%@, id=%@>", 26 | NSStringFromClass(self.class), @(self.screenshotCount), @(self.opened), self.snapIdentifier]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /.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 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | DerivedData 17 | .idea/ 18 | 19 | *.xcbkptlist 20 | *.xccheckout 21 | *.hmap 22 | *.ipa 23 | 24 | *.swp 25 | *.lock 26 | *.xcuserstate 27 | 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Icon must end with two \r 32 | Icon 33 | 34 | # Thumbnails 35 | ._* 36 | 37 | # Files that might appear on external disk 38 | .Spotlight-V100 39 | .Trashes 40 | 41 | # Directories potentially created on remote AFP share 42 | .AppleDB 43 | .AppleDesktop 44 | Network Trash Folder 45 | Temporary Items 46 | .apdisk 47 | Example/Pods/**/* 48 | Example/SnapchatKit.xcworkspace 49 | Example/SnapchatKit.xcworkspace/contents.xcworkspacedata 50 | 51 | Login.h 52 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryOptions.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryOptions.m 3 | // SnapchatKitTests 4 | // 5 | // Created by Harry Gulliford on 30/06/2015. 6 | // Copyright (c) 2015 Harry Gulliford. All rights reserved. 7 | // 8 | 9 | #import "SKStoryOptions.h" 10 | 11 | @implementation SKStoryOptions 12 | 13 | + (instancetype)storyWithText:(NSString *)text timer:(NSTimeInterval)timer { 14 | SKStoryOptions *options = [self new]; 15 | options.text = text; 16 | options.timer = timer; 17 | return options; 18 | } 19 | 20 | - (id)init { 21 | self = [super init]; 22 | if (self) { 23 | _text = @""; 24 | _timer = 3; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)setText:(NSString *)text { 31 | _text = text ?: @""; 32 | } 33 | 34 | - (void)setTimer:(NSTimeInterval)timer { 35 | NSParameterAssert(timer > 0); 36 | _timer = timer; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryOptions.h 3 | // SnapchatKitTests 4 | // 5 | // Created by Harry Gulliford on 30/06/2015. 6 | // Copyright (c) 2015 Harry Gulliford. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** The purpose of this class is to simplify the act of sending a snpa. */ 12 | @interface SKStoryOptions : NSObject 13 | 14 | /** 15 | If you wish, you can also just create an instance of this class with \c +new and customize it. 16 | @param recipients An array of username strings. 17 | */ 18 | + (instancetype)storyWithText:(NSString *)text timer:(NSTimeInterval)timer; 19 | 20 | /** An array of username strings. */ 21 | @property (nonatomic) NSString *text; 22 | /** Defaults to \c NO. */ 23 | @property (nonatomic) BOOL cameraFrontFacing; 24 | /** Defaults to 3. Ignored for videos. */ 25 | @property (nonatomic) NSTimeInterval timer; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSDictionary+SnapchatKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+SnapchatKit.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/22/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary (JSON) 12 | 13 | @property (nonatomic, readonly) NSString *JSONString; 14 | - (NSString *)JWTStringWithSecret:(NSString *)secret; 15 | 16 | @end 17 | 18 | 19 | @interface NSDictionary (Util) 20 | /** \c entryLimit must be greater than \c 0. */ 21 | - (NSArray *)split:(NSUInteger)entryLimit; 22 | 23 | - (NSDictionary *)dictionaryByReplacingValuesForKeys:(NSDictionary *)dictionary; 24 | - (NSDictionary *)dictionaryByReplacingKeysWithNewKeys:(NSDictionary *)oldKeysToNewKeys; 25 | 26 | @property (nonatomic, readonly) NSArray *allKeyPaths; 27 | 28 | @end 29 | 30 | #define SKMergeDictionaries(a, b) [a dictionaryByReplacingValuesForKeys: b] -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnapResponse.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnapResponse.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/29/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SKThing.h" 11 | 12 | /** Passed to the completion of both of the \c -[SKClient sendSnap:...] methods. */ 13 | @interface SKSnapResponse : SKThing 14 | 15 | /** An array of \c SKSentSnap objects, not to be confused with outgoing \c SKSnap objects. */ 16 | @property (nonatomic, readonly) NSArray *sentSnaps; 17 | @property (nonatomic, readonly) BOOL success; 18 | 19 | @end 20 | 21 | /** Used as part of the \c SKSnapResponse class; not a counterpart of \c SKSnap. */ 22 | @interface SKSentSnap : SKThing 23 | @property (nonatomic, readonly) NSString *sender; 24 | @property (nonatomic, readonly) NSString *identifier; 25 | @property (nonatomic, readonly) NSDate *timestamp; 26 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/TBQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBQueue.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "TBQueue.h" 10 | 11 | @implementation TBQueue 12 | 13 | - (id)init { 14 | self = [super init]; 15 | if (self) { 16 | _list = [NSMutableArray new]; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | // Insert at the front 23 | - (void)enqueue:(id)obj { 24 | [_list insertObject:obj atIndex:0]; 25 | } 26 | 27 | // Remove at the end 28 | - (id)take { 29 | id ret = _list.lastObject; 30 | if (ret) { 31 | [_list removeLastObject]; 32 | } 33 | 34 | return ret; 35 | } 36 | 37 | - (void)clear { 38 | [_list removeAllObjects]; 39 | } 40 | 41 | - (id)front { 42 | return _list.lastObject; 43 | } 44 | 45 | - (NSUInteger)count { 46 | return _list.count; 47 | } 48 | 49 | - (BOOL)isEmpty { 50 | return _list.count == 0; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/SnapchatKit.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SnapchatKit", 3 | "version": "0.6.1", 4 | "summary": "An Objective-C implementation of the unofficial Snapchat API.", 5 | "homepage": "https://github.com/ThePantsThief/SnapchatKit", 6 | "license": "MIT", 7 | "authors": { 8 | "ThePantsThief": "tannerbennett@me.com" 9 | }, 10 | "source": { 11 | "git": "https://github.com/ThePantsThief/SnapchatKit.git", 12 | "tag": "0.6.1" 13 | }, 14 | "social_media_url": "https://twitter.com/ThePantsThief", 15 | "requires_arc": true, 16 | "platforms": { 17 | "ios": "7.0", 18 | "osx": "10.8" 19 | }, 20 | "source_files": [ 21 | "Pod/Classes/*", 22 | "Pod/Classes/**/*", 23 | "Pod/Dependencies/*", 24 | "Pod/Dependencies/**/*" 25 | ], 26 | "dependencies": { 27 | "CocoaAsyncSocket": [ 28 | 29 | ], 30 | "Mantle": [ 31 | "~> 2.0" 32 | ] 33 | }, 34 | "libraries": "z" 35 | } 36 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryNote.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryNote.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | /** Story notes carry information about how someone viewed a certain story. */ 12 | @interface SKStoryNote : SKThing 13 | 14 | /** Who viewed the story. */ 15 | @property (nonatomic, readonly) NSString *viewer; 16 | /** When the story was viewed by \c viewer. */ 17 | @property (nonatomic, readonly) NSDate *viewDate; 18 | /** Whether \c viewer took a screenshot of the story .*/ 19 | @property (nonatomic, readonly) BOOL screenshot; 20 | 21 | /** Obscure data. Not sure what it's all for. Keys are as follows: 22 | mField = "123456.023Z"; 23 | mId = "username~unixtime"; 24 | mKey = "story:{username}:YYYYMMDD"; 25 | */ 26 | @property (nonatomic, readonly) NSDictionary *storyPointer; 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConversationMessagePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKConversationMessagePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 3/25/16. 6 | // 7 | // 8 | 9 | #import "SKConversationMessagePacket.h" 10 | 11 | @implementation SKConversationMessagePacket 12 | @dynamic canSendOverHTTP; 13 | @dynamic needsACK; 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 16 | return [@{@"auth": @"header.auth", 17 | @"connSequenceNumber": @"header.conn_seq_num", 18 | @"header_conversationIdentifier": @"header.conv_id", 19 | @"from": @"header.from", 20 | @"to": @"header.to", 21 | @"retried": @"retried"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 22 | } 23 | 24 | - (NSString *)description { 25 | return [NSString stringWithFormat:@"<%@ from=%@, to=%@>", 26 | NSStringFromClass(self.class), self.from, self.to.firstObject]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSimpleUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKSimpleUser.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SnapchatKit-Constants.h" 11 | 12 | #import "SKThing.h" 13 | 14 | @interface SKSimpleUser : SKThing 15 | 16 | @property (nonatomic, readonly) NSString *username; 17 | @property (nonatomic, readonly) NSString *displayName; 18 | @property (nonatomic, readonly) NSString *userIdentifier; 19 | @property (nonatomic, readonly) BOOL addedIncoming; 20 | @property (nonatomic, readonly) BOOL ignoredLink; 21 | @property (nonatomic, readonly) NSDate *expiration; 22 | /** When the request was accepted. */ 23 | @property (nonatomic, readonly) NSDate *addedBack; 24 | /** Self explainatory. Status of the relationship between you and this user. */ 25 | @property (nonatomic, readonly) SKFriendStatus friendStatus; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConversationMessageResponsePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKConversationMessageResponsePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKConversationMessageResponsePacket.h" 10 | 11 | @implementation SKConversationMessageResponsePacket 12 | 13 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 14 | return [@{@"ACKIdentifier": @"ack_id", 15 | @"conversationIdentifier": @"conv_id", 16 | @"failureReason": @"failure_reason", 17 | @"successful": @"success", 18 | @"timestamp": @"timestamp"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 19 | } 20 | 21 | MTLTransformPropertyDate(timestamp) 22 | 23 | - (NSString *)description { 24 | return [NSString stringWithFormat:@"<%@ successful=%@, failure=%@, conv_id=%@, date=%@>", 25 | NSStringFromClass(self.class), @(self.successful), self.failureReason, self.conversationIdentifier, self.timestamp]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSharedStoryDescription.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKSharedStoryDescription.h 3 | // SnapchatKit-OSX-Demo 4 | // 5 | // Created by Tanner Bennett on 7/17/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | @interface SKSharedStoryDescription : SKThing 12 | 13 | /** ie "Campaign 2016 is a collection of Snaps from Snapchatters in Iowa." */ 14 | @property (nonatomic, readonly) NSString *friendNote; 15 | /** ie "While you're here, you may submit Snaps to Our Campaign Story. To opt out of this location-based feature, turn off Filters in Settings." */ 16 | @property (nonatomic, readonly) NSString *localPostBody; 17 | /** ie "Post Snap to Campaign?" */ 18 | @property (nonatomic, readonly) NSString *localPostTitle; 19 | /** ie "Campaign 2016 is a collection of Snaps from Snapchatters in Iowa." */ 20 | @property (nonatomic, readonly) NSString *localViewBody; 21 | /** ie "Our Story" */ 22 | @property (nonatomic, readonly) NSString *localViewTitle; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKTrophyMetrics.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKTrophyMetrics.h 3 | // Pods 4 | // 5 | // Created by Tanner on 12/29/15. 6 | // 7 | // 8 | 9 | #import 10 | 11 | 12 | /// The purpsoe of this class is to simplify the use of \c updateTrophiesWithMetrics:completion: 13 | @interface SKTrophyMetrics : NSObject 14 | 15 | @property (nonatomic) BOOL frontFacing; 16 | @property (nonatomic) BOOL manyColors; 17 | @property (nonatomic) BOOL video; 18 | @property (nonatomic) BOOL postingNSnaps; 19 | @property (nonatomic) BOOL oneFilter; 20 | @property (nonatomic) BOOL twoFilters; 21 | @property (nonatomic) BOOL fullZoom; 22 | @property (nonatomic) BOOL coldFilter; 23 | @property (nonatomic) BOOL hotFilter; 24 | @property (nonatomic) BOOL blackAndWhite; 25 | @property (nonatomic) BOOL nightMode; 26 | @property (nonatomic) BOOL bigText; 27 | @property (nonatomic) BOOL earlyMorning; 28 | @property (nonatomic) BOOL frontFlash; 29 | 30 | @property (nonatomic, readonly) NSDictionary *metrics; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryUpdater.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryUpdater.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/16/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKStoryUpdater.h" 10 | #import "SKStory.h" 11 | 12 | #import "NSString+SnapchatKit.h" 13 | 14 | @implementation SKStoryUpdater 15 | 16 | + (instancetype)viewedStory:(SKStory *)story at:(NSDate *)date screenshots:(NSUInteger)sscount { 17 | NSParameterAssert([story isKindOfClass:[SKStory class]]); 18 | return [[self alloc] initWithStoryIdentifier:story.identifier viewedOn:date sscount:sscount]; 19 | } 20 | 21 | - (id)initWithStoryIdentifier:(NSString *)identifier viewedOn:(NSDate *)date sscount:(NSUInteger)sscount { 22 | NSParameterAssert(identifier); 23 | self = [super init]; 24 | if (self) { 25 | _storyID = identifier; 26 | _timestamp = [NSString timestampFrom:date]; 27 | _screenshotCount = sscount; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Example/SnapchatKit-OSX/SnapchatKit-OSX/TBTimer.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBTimer.m 3 | // BU Eats 4 | // 5 | // Created by Tanner on 4/24/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "TBTimer.h" 10 | 11 | @implementation TBTimer 12 | 13 | #pragma mark Timer 14 | 15 | + (instancetype)timer { 16 | static TBTimer *sharedTimeInterval = nil; 17 | static dispatch_once_t onceToken; 18 | dispatch_once(&onceToken, ^{ 19 | sharedTimeInterval = [self new]; 20 | }); 21 | 22 | return sharedTimeInterval; 23 | } 24 | 25 | + (void)startTimer { 26 | TBTimer *timer = self.timer; 27 | printf("Timer: started\n"); 28 | timer->_startTime = [NSDate date]; 29 | timer->_endTime = nil; 30 | } 31 | 32 | + (CGFloat)lap { 33 | TBTimer *timer = self.timer; 34 | timer->_endTime = [NSDate date]; 35 | printf("Timer: elapsed %f\n", [timer.endTime timeIntervalSinceDate:timer.startTime]); 36 | 37 | return [timer.endTime timeIntervalSinceDate:timer.startTime]; 38 | } 39 | 40 | @end -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/TextFormat.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | @interface PBTextFormat : NSObject { 19 | 20 | } 21 | 22 | + (SInt32) parseInt32:(NSString*) text; 23 | + (SInt32) parseUInt32:(NSString*) text; 24 | + (SInt64) parseInt64:(NSString*) text; 25 | + (SInt64) parseUInt64:(NSString*) text; 26 | 27 | + (NSData*) unescapeBytes:(NSString*) input; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSMutableURLRequest+Util.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableURLRequest+Util.m 3 | // Pods 4 | // 5 | // Created by Tanner on 2/21/16. 6 | // 7 | // 8 | 9 | #import "NSMutableURLRequest+Util.h" 10 | #import "NSString+SnapchatKit.h" 11 | 12 | 13 | @implementation NSMutableURLRequest (Util) 14 | 15 | + (instancetype)POST:(NSString *)urlString body:(NSDictionary *)body headers:(NSDictionary *)headers { 16 | NSURL *url = [NSURL URLWithString:urlString]; 17 | if (!url) { [NSException raise:NSInvalidArgumentException format:@"Tried to create an NSURL with a malformed URL string: %@", urlString]; } 18 | 19 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 20 | request.HTTPMethod = @"POST"; 21 | request.HTTPBody = [[NSString queryStringWithParams:body] dataUsingEncoding:NSUTF8StringEncoding]; 22 | 23 | [headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) { 24 | [request setValue:value forHTTPHeaderField:key]; 25 | }]; 26 | 27 | return request; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKChatMessagePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKChatMessagePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/6/16. 6 | // 7 | // 8 | 9 | #import "SKChatMessagePacket.h" 10 | #import "SnapchatKit-Constants.h" 11 | 12 | 13 | @implementation SKChatMessagePacket 14 | 15 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 16 | return [@{@"text": @"body.text", 17 | @"media": @"body.media", 18 | @"messageType": @"body.type", 19 | @"attributes": @"body.attributes", 20 | @"chatMessageIdentifier": @"chat_message_id", 21 | @"state": @"saved_state", 22 | @"sequenceNumber": @"seq_num", 23 | @"timestamp": @"timestamp"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 24 | } 25 | 26 | MTLTransformPropertyDate(timestamp) 27 | 28 | - (NSString *)description { 29 | return [NSString stringWithFormat:@"<%@ text=%@, type=%@, date=%@>", 30 | NSStringFromClass(self.class), self.text, self.messageType, self.timestamp]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/MutableExtensionRegistry.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "ExtensionRegistry.h" 19 | 20 | @interface PBMutableExtensionRegistry : PBExtensionRegistry { 21 | @private 22 | NSMutableDictionary* mutableClassMap; 23 | } 24 | 25 | + (PBMutableExtensionRegistry*) registry; 26 | 27 | - (void) addExtension:(id) extension; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/AbstractMessageBuilder.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "MessageBuilder.h" 19 | 20 | /** 21 | * A partial implementation of the {@link Message.Builder} interface which 22 | * implements as many methods of that interface as possible in terms of 23 | * other methods. 24 | */ 25 | @interface PBAbstractMessageBuilder : NSObject { 26 | } 27 | 28 | @end 29 | 30 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKFoundFriend.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKFoundFriend.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKFoundFriend.h" 10 | 11 | @implementation SKFoundFriend 12 | 13 | - (NSString *)description { 14 | return [NSString stringWithFormat:@"<%@ displayn=%@, username=%@, private=%d>", 15 | NSStringFromClass(self.class), self.displayName, self.username, self.isPrivate]; 16 | } 17 | 18 | #pragma mark - Mantle 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 21 | return @{@"displayName": @"diplay", 22 | @"username": @"name", 23 | @"isPrivate": @"type"}; 24 | } 25 | 26 | #pragma mark - Equality 27 | 28 | - (BOOL)isEqual:(id)object { 29 | if ([object isKindOfClass:[SKFoundFriend class]]) 30 | return [self isEqualToFoundFriend:object]; 31 | 32 | return [super isEqual:object]; 33 | } 34 | 35 | - (BOOL)isEqualToFoundFriend:(SKFoundFriend *)found { 36 | return [self.username isEqualToString:found.username]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Example/SnapchatKit/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 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 ThePantsThief 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pod/Classes/SnapchatKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // SnapchatKit-Constants.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SnapchatKit-Constants.h" 10 | 11 | #import "SKClient.h" 12 | #import "SKClient+Account.h" 13 | #import "SKClient+Chat.h" 14 | #import "SKClient+Device.h" 15 | #import "SKClient+Friends.h" 16 | #import "SKClient+Snaps.h" 17 | #import "SKClient+Stories.h" 18 | 19 | #import "SKAddedFriend.h" 20 | #import "SKAvatar.h" 21 | #import "SKBlob.h" 22 | #import "SKCashTransaction.h" 23 | #import "SKChatRoom.h" 24 | #import "SKConversation.h" 25 | #import "SKConversationState.h" 26 | #import "SKFoundFriend.h" 27 | #import "SKMessage.h" 28 | #import "SKSession.h" 29 | #import "SKSharedStoryDescription.h" 30 | #import "SKSimpleUser.h" 31 | #import "SKSnap.h" 32 | #import "SKSnapOptions.h" 33 | #import "SKSnapResponse.h" 34 | #import "SKStory.h" 35 | #import "SKStoryOptions.h" 36 | #import "SKStoryCollection.h" 37 | #import "SKStoryNote.h" 38 | #import "SKTrophy.h" 39 | #import "SKTrophyMetrics.h" 40 | #import "SKUser.h" 41 | #import "SKUserStory.h" -------------------------------------------------------------------------------- /Pod/Classes/Model/SKNearbyUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKNearbyUser.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 7/3/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKNearbyUser.h" 10 | 11 | @implementation SKNearbyUser 12 | 13 | - (NSString *)description { 14 | return [NSString stringWithFormat:@"<%@ username=%@, id=%@>", 15 | NSStringFromClass(self.class), _username, _identifier]; 16 | } 17 | 18 | #pragma mark - Mantle 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 21 | return @{@"username": @"username", 22 | @"identifier": @"user_id"}; 23 | } 24 | 25 | #pragma mark - Equality 26 | 27 | - (BOOL)isEqual:(id)object { 28 | if ([object isKindOfClass:[SKNearbyUser class]]) 29 | return [self isEqualToNearbyUser:object]; 30 | 31 | return [super isEqual:object]; 32 | } 33 | 34 | - (BOOL)isEqualToNearbyUser:(SKNearbyUser *)user { 35 | return [user.identifier isEqualToString:_identifier] && [user.username isEqualToString:_username]; 36 | } 37 | 38 | - (NSUInteger)hash { 39 | return self.identifier.hash ^ self.username.hash; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/Bootstrap.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "ForwardDeclarations.h" 19 | 20 | #import "CodedInputStream.h" 21 | #import "CodedOutputStream.h" 22 | #import "ExtendableMessage.h" 23 | #import "ExtendableMessageBuilder.h" 24 | #import "ExtensionRegistry.h" 25 | #import "GeneratedMessage.h" 26 | #import "GeneratedMessageBuilder.h" 27 | #import "MessageBuilder.h" 28 | #import "UnknownFieldSet.h" 29 | #import "UnknownFieldSetBuilder.h" 30 | #import "Utilities.h" 31 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConnectPacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKConnectPacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKConnectPacket.h" 10 | #import "NSDictionary+SnapchatKit.h" 11 | #import "NSString+SnapchatKit.h" 12 | 13 | 14 | @implementation SKConnectPacket 15 | 16 | + (instancetype)withUsername:(NSString *)username auth:(NSDictionary *)auth { 17 | SKConnectPacket *packet = [self packet:@{@"username": username, @"auth": auth, 18 | @"type": @"connect", 19 | @"id": SKUniqueIdentifier(), 20 | @"platform": @"iOS", 21 | @"version": @"8.4", 22 | @"app_version": @"9.26.0.1"}]; 23 | return packet; 24 | } 25 | 26 | - (NSString *)description { 27 | return [NSString stringWithFormat:@"<%@ username=%@, platform=%@, version=%@, app_version=%@>", 28 | NSStringFromClass(self.class), self.json[@"username"], self.json[@"platform"], 29 | self.json[@"version"], self.json[@"app_version"]]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKFilter.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | @interface SKFilter : SKThing 12 | 13 | @property (nonatomic, readonly) NSString *identifier; 14 | @property (nonatomic, readonly) NSInteger priority; 15 | 16 | /** Array of CLLocation objects. */ 17 | @property (nonatomic, readonly) NSArray *coordinates; 18 | @property (nonatomic, readonly) NSString *geofenceIdentifier; 19 | 20 | @property (nonatomic, readonly) BOOL hideSponsoredSlug; 21 | /** Whether the filter is animated or not. */ 22 | @property (nonatomic, readonly) BOOL isDynamic; 23 | /** Whether the story is sponsored. */ 24 | @property (nonatomic, readonly) BOOL isSponsored; 25 | @property (nonatomic, readonly) NSURL *imageURL; 26 | 27 | /** Array of strings such as "scale_aspect_fit" and "bottom" indicating where the filter should be positioned. */ 28 | @property (nonatomic, readonly) NSArray *position; 29 | @property (nonatomic, readonly) BOOL prepositioned; 30 | @property (nonatomic, readonly) NSURL *prepositionedImageURL; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/WireFormat.m: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "WireFormat.h" 19 | 20 | #import "Utilities.h" 21 | 22 | SInt32 PBWireFormatMakeTag(SInt32 fieldNumber, SInt32 wireType) { 23 | return (fieldNumber << PBWireFormatTagTypeBits) | wireType; 24 | } 25 | 26 | 27 | SInt32 PBWireFormatGetTagWireType(SInt32 tag) { 28 | return tag & PBWireFormatTagTypeMask; 29 | } 30 | 31 | 32 | SInt32 PBWireFormatGetTagFieldNumber(SInt32 tag) { 33 | return logicalRightShift32(tag, PBWireFormatTagTypeBits); 34 | } 35 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnapOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnapOptions.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/16/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** The purpose of this class is to simplify the act of sending a snpa. */ 12 | @interface SKSnapOptions : NSObject 13 | 14 | /** If you wish, you can also just create an instance of this class with \c +new and customize it. 15 | @param recipients An array of username strings. 16 | @param text The text sent in the snap. 17 | @param timer The length of the snap. */ 18 | + (instancetype)sendTo:(NSArray *)recipients text:(NSString *)text for:(NSTimeInterval)timer; 19 | 20 | /** An array of username strings. */ 21 | @property (nonatomic) NSArray *recipients; 22 | /** The text sent in the snap. */ 23 | @property (nonatomic) NSString *text; 24 | /** Whether the camera is front facing or nit. */ 25 | @property (nonatomic) BOOL cameraFrontFacing; 26 | /** Whether the snap is a reply to a previous snap. */ 27 | @property (nonatomic) BOOL isReply; 28 | /** The length of the snap. Defaults to 3. */ 29 | @property (nonatomic) NSTimeInterval timer; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKChatInputStream.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKChatInputStream.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKChatInputStream.h" 10 | 11 | #import "SKConnectPacket.h" 12 | #import "SKConnectResponsePacket.h" 13 | #import "SKChatMessagePacket.h" 14 | #import "SKPresencePacket.h" 15 | #import "SKMessageStatePacket.h" 16 | #import "SKReleaseMessagePacket.h" 17 | #import "SKErrorPacket.h" 18 | #import "SKProtocolErrorPacket.h" 19 | #import "SKConversationMessageResponsePacket.h" 20 | #import "SKSnapStatePacket.h" 21 | #import "SKPingResponsePacket.h" 22 | 23 | 24 | @implementation NSInputStream (SKChatInputStream) 25 | 26 | // For testing 27 | - (NSData *)readData { 28 | int buffer[1]; 29 | if ([self read:buffer maxLength:4] > 0) { 30 | int length = NSSwapInt(buffer[0]); 31 | 32 | if (length >= USHRT_MAX || length < 0) { return nil; } 33 | 34 | char buff[length]; 35 | if ([self read:buff maxLength:length] > 0) { 36 | return [NSData dataWithBytes:buff length:length]; 37 | } 38 | } 39 | 40 | return nil; 41 | } 42 | 43 | - (SKPacket *)recievePacket { 44 | return [SKPacket packetFromData:[self readData]]; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/GeneratedMessage.m: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "GeneratedMessage.h" 19 | 20 | #import "UnknownFieldSet.h" 21 | 22 | @interface PBGeneratedMessage () 23 | @property (strong) PBUnknownFieldSet* unknownFields; 24 | @end 25 | 26 | 27 | @implementation PBGeneratedMessage 28 | 29 | @synthesize unknownFields; 30 | 31 | - (instancetype) init { 32 | if ((self = [super init])) { 33 | self.unknownFields = [PBUnknownFieldSet defaultInstance]; 34 | memoizedSerializedSize = -1; 35 | } 36 | 37 | return self; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/GeneratedMessageBuilder.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "AbstractMessageBuilder.h" 19 | 20 | @class PBUnknownFieldSetBuilder; 21 | 22 | @interface PBGeneratedMessageBuilder : PBAbstractMessageBuilder { 23 | } 24 | 25 | /* @protected */ 26 | - (BOOL) parseUnknownField:(PBCodedInputStream*) input 27 | unknownFields:(PBUnknownFieldSetBuilder*) unknownFields 28 | extensionRegistry:(PBExtensionRegistry*) extensionRegistry 29 | tag:(SInt32) tag; 30 | 31 | - (void) checkInitialized; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnapOptions.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnapOptions.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/16/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKSnapOptions.h" 10 | 11 | @implementation SKSnapOptions 12 | 13 | + (instancetype)sendTo:(NSArray *)recipients text:(NSString *)text for:(NSTimeInterval)timer { 14 | SKSnapOptions *options = [self new]; 15 | options.recipients = recipients; 16 | options.text = text; 17 | options.timer = timer; 18 | return options; 19 | } 20 | 21 | - (id)init { 22 | self = [super init]; 23 | if (self) { 24 | _recipients = @[]; 25 | _text = @""; 26 | _timer = 3; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | - (void)setRecipients:(NSArray *)recipients { 33 | NSParameterAssert(recipients.count); 34 | _recipients = recipients; 35 | // for (NSString *r in recipients) 36 | // NSParameterAssert([r isKindOfClass:[NSString class]]); 37 | } 38 | 39 | - (void)setText:(NSString *)text { 40 | _text = text ?: @""; 41 | } 42 | 43 | - (void)setTimer:(NSTimeInterval)timer { 44 | NSParameterAssert(timer > 0); 45 | _timer = timer; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKNewConversation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKNewConversation.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 7/11/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKNewConversation.h" 10 | #import "NSString+SnapchatKit.h" 11 | #import "SKClient.h" 12 | 13 | @implementation SKNewConversation 14 | 15 | + (instancetype)newConvoWithAuth:(NSDictionary *)macAndPayload withSender:(NSString *)sender otherUser:(NSString *)recipient { 16 | return [[self alloc] initWithDictionary:macAndPayload withSender:sender otherUser:recipient]; 17 | } 18 | 19 | - (id)initWithDictionary:(NSDictionary *)json withSender:(NSString *)sender otherUser:(NSString *)recipient { 20 | NSParameterAssert(json); NSParameterAssert(recipient); NSParameterAssert(sender); 21 | 22 | self = [super init]; 23 | if (self) { 24 | _recipient = recipient; 25 | _messagingAuth = json; 26 | _mac = json[@"mac"]; 27 | _payload = json[@"payload"]; 28 | _state = @{@"conversation_state": @{@"user_sequences": @{sender: @0, recipient: @0}}}; 29 | _identifier = [NSString SCIdentifierWith:sender and:recipient]; 30 | } 31 | 32 | return self; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/MutableField.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "Field.h" 19 | 20 | @class PBUnknownFieldSet; 21 | 22 | @interface PBMutableField : PBField 23 | 24 | + (PBMutableField *)field; 25 | 26 | - (PBMutableField *)mergeFromField:(PBField *)other; 27 | 28 | - (PBMutableField *)clear; 29 | - (PBMutableField *)addVarint:(SInt64)value; 30 | - (PBMutableField *)addFixed32:(SInt32)value; 31 | - (PBMutableField *)addFixed64:(SInt64)value; 32 | - (PBMutableField *)addLengthDelimited:(NSData *)value; 33 | - (PBMutableField *)addGroup:(PBUnknownFieldSet *)value; 34 | 35 | @end -------------------------------------------------------------------------------- /Example/SnapchatKit/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConversationState.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKConversationState.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/6/16. 6 | // 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | 12 | /** 13 | Keys: 14 | 15 | - "user_chat_releases" 16 | Contains a dictionary with keys for each participant, 17 | mapping the number of messages from each participant, as 18 | they see it. So if Bob sends Sally a message and Sally hasn't 19 | read it, state["user_chat_releases"]["Sally"]["Bob"] will 20 | be one less than state["user_chat_releases"]["Bob"]["Sally"], 21 | because Sally has not read it yet but Bob can see it. 22 | 23 | - "user_sequences" 24 | A dictionary with keys for each participant, mapping 25 | the total number of messages and snaps sent by that user. 26 | 27 | - "user_snap_releases" 28 | Same as "user_chat_releases" but with timestamps. Might just be for snaps. 29 | */ 30 | @interface SKConversationState : SKThing 31 | 32 | + (instancetype)state:(NSDictionary *)json recipient:(NSString *)recipient; 33 | 34 | @property (nonatomic, readonly) NSUInteger recipientUnreadCount; 35 | @property (nonatomic, readonly) NSUInteger senderUnreadCount; 36 | 37 | @property (nonatomic, readonly) NSUInteger recipientSentCount; 38 | @property (nonatomic, readonly) NSUInteger senderSentCount; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ForwardDeclarations.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | @protocol PBMessage; 19 | @protocol PBMessageBuilder; 20 | @protocol PBExtensionField; 21 | 22 | @class PBAbstractMessage; 23 | @class PBCodedInputStream; 24 | @class PBCodedOutputStream; 25 | @class PBConcreteExtensionField; 26 | @class PBExtendableMessageBuilder; 27 | @class PBExtendableMessage; 28 | @class PBExtensionRegistry; 29 | @class PBField; 30 | @class PBGeneratedMessage; 31 | @class PBGeneratedMessageBuilder; 32 | @class PBMutableExtensionRegistry; 33 | @class PBMutableField; 34 | @class PBUnknownFieldSet; 35 | @class PBUnknownFieldSetBuilder; 36 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKTrophy.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKTrophy.m 3 | // Pods 4 | // 5 | // Created by Tanner on 12/23/15. 6 | // 7 | // 8 | 9 | #import "SKTrophy.h" 10 | 11 | @implementation SKTrophy 12 | 13 | - (NSString *)description { 14 | return [NSString stringWithFormat:@"<%@ label=%@ unicode=%@> Stages:\n%@", 15 | NSStringFromClass(self.class), _label, _unicode, _stages.description]; 16 | } 17 | 18 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 19 | return @{@"label": @"label", 20 | @"unicode": @"unicode", 21 | @"stages": @"stages"}; 22 | } 23 | 24 | + (NSValueTransformer *)stagesJSONTransformer { return [self sk_modelArrayTransformerForClass:[SKTrophyStage class]]; } 25 | 26 | @end 27 | 28 | 29 | @implementation SKTrophyStage 30 | 31 | - (NSString *)description { 32 | return _unicode; 33 | } 34 | 35 | - (NSString *)debugDescription { 36 | return [NSString stringWithFormat:@"<%@ label=%@ unicode=%@ status=%@>", 37 | NSStringFromClass(self.class), _label, _unicode, _status]; 38 | } 39 | 40 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 41 | return @{@"label": @"label", 42 | @"unicode": @"unicode", 43 | @"status": @"status", 44 | @"achievedOn": @"achieved_timestamp"}; 45 | } 46 | 47 | MTLTransformPropertyDate(achievedOn) 48 | 49 | @end -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSArray+SnapchatKit.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+SnapchatKit.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/22/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "NSArray+SnapchatKit.h" 10 | #import "Mantle.h" 11 | 12 | @implementation NSArray (JSON) 13 | 14 | - (NSString *)JSONString { 15 | NSData *data = [NSJSONSerialization dataWithJSONObject:self options:0 error:nil]; 16 | return data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : @"[]"; 17 | } 18 | 19 | - (NSArray *)dictionaryValues { 20 | NSMutableArray *jsons = [NSMutableArray array]; 21 | for (idfoo in self) 22 | [jsons addObject:[MTLJSONAdapter JSONDictionaryFromModel:foo error:nil]]; 23 | 24 | return jsons.copy; 25 | } 26 | 27 | @end 28 | 29 | @implementation NSArray (REST) 30 | 31 | - (NSString *)recipientsString { 32 | if (!self.count) return @"[]"; 33 | 34 | NSMutableString *string = [NSMutableString string]; 35 | [string appendString:@"["]; 36 | 37 | for (NSString *recipient in self) 38 | [string appendFormat:@"\"%@\",", recipient]; 39 | 40 | [string deleteCharactersInRange:NSMakeRange(string.length-1, 1)]; 41 | [string appendString:@"]"]; 42 | 43 | return string; 44 | } 45 | 46 | @end -------------------------------------------------------------------------------- /Example/SnapchatKit/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 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKAddedFriend.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKAddedFriend.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKAddedFriend.h" 10 | 11 | @implementation SKAddedFriend 12 | 13 | - (NSString *)description { 14 | return [NSString stringWithFormat:@"<%@ add source=%@, username=%@, displayn=%@ pending count=%@>", 15 | NSStringFromClass(self.class), _addSource, self.username, self.displayName, @(_pendingSnaps)]; 16 | } 17 | 18 | #pragma mark - Mantle 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 21 | return [@{@"addSource": @"add_source", 22 | @"addSourceType": @"add_source_type", 23 | @"timestamp": @"ts", 24 | @"pendingSnaps": @"pending_snaps_count"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 25 | } 26 | 27 | + (NSValueTransformer *)addSourceTypeJSONTransformer { 28 | return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *type, BOOL *success, NSError *__autoreleasing *error) { 29 | return @(SKAddSourceFromString(type)); 30 | } reverseBlock:^id(NSNumber *type, BOOL *success, NSError *__autoreleasing *error) { 31 | return SKStringFromAddSource(type.integerValue); 32 | }]; 33 | } 34 | 35 | MTLTransformPropertyDate(timestamp) 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKUser.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKSimpleUser.h" 10 | 11 | @interface SKUser : SKSimpleUser 12 | 13 | /** See http://i.imgur.com/PfFbw59.jpg */ 14 | @property (nonatomic, readonly) NSString *friendmojiString; 15 | /** An array of strings representing which friendmojis to use. See http://i.imgur.com/PfFbw59.jpg */ 16 | @property (nonatomic, readonly) NSArray *friendmojiTypes; 17 | @property (nonatomic, readonly) NSString *venue; 18 | /** \c nil if the user is not a shared story. */ 19 | @property (nonatomic, readonly) NSString *sharedStoryIdentifier; 20 | 21 | /** Number of days the snap streak has gone on for, if at all. */ 22 | @property (nonatomic, readonly) NSInteger snapStreakCount; 23 | 24 | /** NO if your stories are hidden from this user in "who can see my stories?". */ 25 | @property (nonatomic, readonly) BOOL canSeeCustomStories; 26 | @property (nonatomic, readonly) BOOL needsLove; 27 | @property (nonatomic, readonly) BOOL isSharedStory; 28 | @property (nonatomic, readonly) BOOL isLocalStory; 29 | @property (nonatomic, readonly) BOOL hasCustomDescription; 30 | /** Undocumented. */ 31 | @property (nonatomic, readonly) BOOL decayThumbnail; 32 | /** Undocumented. */ 33 | @property (nonatomic, readonly) NSDate *timestamp; 34 | 35 | @end -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/AbstractMessage.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "Message.h" 19 | 20 | /** 21 | * A partial implementation of the {@link Message} interface which implements 22 | * as many methods of that interface as possible in terms of other methods. 23 | * 24 | * @author Cyrus Najmabadi 25 | */ 26 | @interface PBAbstractMessage : NSObject { 27 | @private 28 | } 29 | 30 | /** 31 | * Writes a string description of the message into the given mutable string 32 | * respecting a given indent. 33 | */ 34 | - (void)writeDescriptionTo:(NSMutableString*) output 35 | withIndent:(NSString*) indent; 36 | 37 | - (void) storeInDictionary: (NSMutableDictionary *) dic; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKAvatar.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKAvatar.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/2/16. 6 | // 7 | // 8 | 9 | #import 10 | #define USE_UIKIT (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) 11 | 12 | #if USE_UIKIT 13 | @import UIKit; 14 | #else 15 | @import AppKit; 16 | #endif 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | @interface SKAvatar : NSObject 20 | 21 | /** @return \c nil if an avatar could not be created from the given data. */ 22 | + (nullable instancetype)avatarWithData:(NSData *)data error:(NSError * _Nullable *)error; 23 | + (NSData *)avatarDataFromImageDatas:(NSArray *)imageDatas; 24 | 25 | @property (nonatomic, readonly) NSString *username; 26 | @property (nonatomic, readonly) NSDate *lastUpdated; 27 | @property (nonatomic, readonly) NSData *data; 28 | 29 | #if USE_UIKIT 30 | /** An animated image representing the avatar. */ 31 | @property (nonatomic, readonly) UIImage *image; 32 | #else 33 | /** Use as you wish, \c nil by default. See \c setImage:freeFrames: */ 34 | @property (nullable, nonatomic, readonly) NSImage *image; 35 | @property (nullable, nonatomic, readonly) NSArray *frames; 36 | /** @param image The image to set to the \c image property. 37 | @param freeFrames Whether or not to release the \c frames property. */ 38 | - (void)setImage:(NSImage *)image freeFrames:(BOOL)freeFrames; 39 | #endif 40 | 41 | @end 42 | NS_ASSUME_NONNULL_END -------------------------------------------------------------------------------- /Pod/Classes/Model/SKCasperCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKCasperCache.h 3 | // Pods 4 | // 5 | // Created by Tanner on 2/21/16. 6 | // 7 | // 8 | 9 | #import 10 | 11 | 12 | /// See the SKCasperCache class for an example implementaiton. 13 | @protocol SKCasperCache 14 | + (id)fromDictionary:(NSDictionary *)oldCache; 15 | @property (nonatomic, readonly) NSDictionary *dictionaryValue; 16 | 17 | /// Add entries to the cache. Takes a full response from the casper serves. 18 | - (void)update:(NSDictionary *)response; 19 | /// Remove all cache entries 20 | - (void)clear; 21 | /// Expected to return the same data returned from the Casper API for a given endpoint. 22 | - (NSDictionary *)objectForKeyedSubscript:(NSString *)endpoint; 23 | @end 24 | 25 | 26 | @interface SKCasperCache : NSObject 27 | 28 | /// Use this for new caches 29 | - (instancetype)init; 30 | /// @return nil if the file was empty or could not be opened. 31 | + (instancetype)fromDictionary:(NSDictionary *)oldCache; 32 | 33 | /// Useful for serialization 34 | @property (nonatomic, readonly) NSDictionary *dictionaryValue; 35 | - (void)clear; 36 | 37 | - (void)update:(NSDictionary *)response; 38 | 39 | /// @return The data for the given endpoint with the keys "headers" and "params" 40 | - (NSDictionary *)dataForEndpoint:(NSString *)endpoint; 41 | /// Same as dataForEndpoint: 42 | - (NSDictionary *)objectForKeyedSubscript:(NSString *)endpoint; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKPresencePacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKPresencePacket.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import "SKPresencePacket.h" 10 | #import "NSDictionary+SnapchatKit.h" 11 | #import "NSString+SnapchatKit.h" 12 | 13 | 14 | @implementation SKPresencePacket 15 | 16 | + (instancetype)presences:(NSDictionary *)presences video:(BOOL)video to:(NSArray *)to from:(NSString *)from auth:(NSString *)auth { 17 | return [self packet:@{@"type": SKStringFromPacketType(SKPacketTypePresence), 18 | @"id": SKUniqueIdentifier().uppercaseString, 19 | @"supports_here": @1, 20 | @"receiving_video": @((int)video), 21 | @"presences": presences, 22 | @"header": @{@"from": from, @"to": to, @"auth": auth}}]; 23 | } 24 | 25 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 26 | return [@{@"hereAuth": @"here_auth", 27 | @"presences": @"presences", 28 | @"receivingVideo": @"receiving_video", 29 | @"supportsHere": @"supports_here"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 30 | } 31 | 32 | - (NSString *)description { 33 | return [NSString stringWithFormat:@"<%@ video=%@, supports_here=%@, to=%@, from=%@> presences:\n%@", 34 | NSStringFromClass(self.class), @(self.receivingVideo), @(self.supportsHere), self.to.firstObject, self.from, self.presences.JSONString]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryNote.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryNote.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKStoryNote.h" 10 | 11 | @implementation SKStoryNote 12 | 13 | - (NSString *)description { 14 | return [NSString stringWithFormat:@"<%@ viewer=%@, screenshot=%d>", 15 | NSStringFromClass(self.class), self.viewer, self.screenshot]; 16 | } 17 | 18 | #pragma mark - Mantle 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 21 | return @{@"viewer": @"viewer", 22 | @"viewDate": @"timestamp", 23 | @"screenshot": @"screenshotted", 24 | @"storyPointer": @"storypointer"}; 25 | } 26 | 27 | + (NSArray *)ignoredJSONKeyPathPrefixes { 28 | static NSArray *ignored = nil; 29 | static dispatch_once_t onceToken; 30 | dispatch_once(&onceToken, ^{ 31 | ignored = @[@"storypointer.mField", @"storypointer.mKey"]; 32 | }); 33 | 34 | return ignored; 35 | } 36 | 37 | MTLTransformPropertyDate(viewDate) 38 | 39 | #pragma mark - Equality 40 | 41 | - (BOOL)isEqual:(id)object { 42 | if ([object isKindOfClass:[SKStoryNote class]]) 43 | return [self isEqualToStoryNote:object]; 44 | 45 | return [super isEqual:object]; 46 | } 47 | 48 | - (BOOL)isEqualToStoryNote:(SKStoryNote *)storyNote { 49 | return [self.viewer isEqualToString:storyNote.viewer] && [self.viewDate isEqualToDate:storyNote.viewDate];; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKPacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKPacket.h 3 | // Pods 4 | // 5 | // Created by Tanner on 1/3/16. 6 | // 7 | // 8 | 9 | #import 10 | #import "Mantle.h" 11 | 12 | 13 | // ts to NSDate transform 14 | #define MTLTransformPropertyDate(property) + (NSValueTransformer *) property##JSONTransformer { \ 15 | return [self sk_dateTransformer]; } 16 | 17 | typedef NS_ENUM(NSUInteger, SKPacketType) 18 | { 19 | SKPacketTypeDefault, 20 | SKPacketTypeConnect, 21 | SKPacketTypeConnectResponse, 22 | SKPacketTypeDisconnect, 23 | SKPacketTypePresence, 24 | SKPacketTypeMessageState, 25 | SKPacketTypeMessageRelease, 26 | SKPacketTypeChatMessage, 27 | SKPacketTypeError, 28 | SKPacketTypeProtocolError, 29 | SKPacketTypeConversationMessageResponse, 30 | SKPacketTypeSnapState, 31 | SKPacketTypePing, 32 | SKPacketTypePingResponse 33 | }; 34 | 35 | NS_ASSUME_NONNULL_BEGIN 36 | 37 | extern NSString * SKStringFromPacketType(SKPacketType); 38 | extern SKPacketType SKPacketTypeFromString(NSString *); 39 | 40 | 41 | @interface SKPacket : MTLModel 42 | 43 | + (instancetype)packet:(NSDictionary *)json; 44 | + (instancetype)packetFromData:(NSData *)data; 45 | 46 | + (NSValueTransformer *)sk_dateTransformer; 47 | 48 | @property (nonatomic, readonly) NSDictionary *json; 49 | @property (nonatomic, readonly) SKPacketType packetType; 50 | @property (nonatomic, readonly) NSString *type; 51 | @property (nonatomic, readonly) NSString *identifier; 52 | 53 | @end 54 | NS_ASSUME_NONNULL_END 55 | 56 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ProtocolBuffers.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | @import Foundation; 19 | #import "Bootstrap.h" 20 | #import "AbstractMessage.h" 21 | #import "AbstractMessageBuilder.h" 22 | #import "CodedInputStream.h" 23 | #import "CodedOutputStream.h" 24 | #import "ConcreteExtensionField.h" 25 | #import "ExtendableMessage.h" 26 | #import "ExtendableMessageBuilder.h" 27 | #import "ExtensionField.h" 28 | #import "ExtensionRegistry.h" 29 | #import "Field.h" 30 | #import "GeneratedMessage.h" 31 | #import "GeneratedMessageBuilder.h" 32 | #import "Message.h" 33 | #import "MessageBuilder.h" 34 | #import "MutableExtensionRegistry.h" 35 | #import "MutableField.h" 36 | #import "PBArray.h" 37 | #import "UnknownFieldSet.h" 38 | #import "UnknownFieldSetBuilder.h" 39 | #import "Utilities.h" 40 | #import "WireFormat.h" 41 | #import "Descriptor.pb.h" 42 | #import "ObjectivecDescriptor.pb.h" 43 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKTrophyMetrics.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKTrophyMetrics.m 3 | // Pods 4 | // 5 | // Created by Tanner on 12/29/15. 6 | // 7 | // 8 | 9 | #import "SKTrophyMetrics.h" 10 | 11 | @implementation SKTrophyMetrics 12 | // , , , 13 | // , , , 14 | // , , , , , 15 | 16 | - (NSDictionary *)metrics { 17 | NSDictionary *metrics = @{@"front_facing_snaps": @(self.frontFacing), 18 | @"many_color_snaps": @(self.manyColors), 19 | @"video_snaps": @(self.video), 20 | @"postin_n_snaps": @(self.postingNSnaps), 21 | @"one_filter_snaps": @(self.oneFilter), 22 | @"two_filter_snaps": @(self.twoFilters), 23 | @"cold_filter_snaps": @(self.coldFilter), 24 | @"hot_filter_snaps": @(self.hotFilter), 25 | @"full_zoom_snaps": @(self.fullZoom), 26 | @"black_and_white_snaps": @(self.blackAndWhite), 27 | @"night_mode_snaps": @(self.nightMode), 28 | @"big_text_snaps": @(self.bigText), 29 | @"front_flash_snaps": @(self.frontFlash), 30 | @"early_morning_snaps": @(self.earlyMorning)}; 31 | 32 | NSMutableDictionary *filtered = metrics.mutableCopy; 33 | for (NSString *key in metrics) 34 | if (![metrics[key] boolValue]) 35 | [filtered removeObjectForKey:key]; 36 | 37 | return filtered.copy; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSharedStoryDescription.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKSharedStoryDescription.m 3 | // SnapchatKit-OSX-Demo 4 | // 5 | // Created by Tanner Bennett on 7/17/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKSharedStoryDescription.h" 10 | 11 | @implementation SKSharedStoryDescription 12 | 13 | - (NSString *)description { 14 | return [NSString stringWithFormat:@"<%@ friend=\"%@\", local view=\"%@\", local post=\"%@\">", 15 | NSStringFromClass(self.class), self.friendNote, self.localViewTitle, self.localViewBody]; 16 | } 17 | 18 | #pragma mark - Mantle 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 21 | return @{@"friendNote": @"FRIEND", 22 | @"localPostBody": @"LOCAL_POST_BODY", 23 | @"localPostTitle": @"LOCAL_POST_TITLE", 24 | @"localViewBody": @"LOCAL_VIEW_BODY", 25 | @"localViewTitle": @"LOCAL_VIEW_TITLE"}; 26 | } 27 | 28 | #pragma mark - Equality 29 | 30 | - (BOOL)isEqual:(id)object { 31 | if ([object isKindOfClass:[SKSharedStoryDescription class]]) 32 | return [self isEqualToSharedStoryDescription:object]; 33 | 34 | return [super isEqual:object]; 35 | } 36 | 37 | - (BOOL)isEqualToSharedStoryDescription:(SKSharedStoryDescription *)ssd { 38 | return [self.friendNote isEqualToString:ssd.friendNote] && 39 | [self.localPostBody isEqualToString:ssd.localPostBody] && 40 | [self.localPostTitle isEqualToString:ssd.localPostTitle] && 41 | [self.localViewBody isEqualToString:ssd.localViewBody] && 42 | [self.localViewTitle isEqualToString:ssd.localViewTitle]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SNTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SNTableViewController.m 3 | // SnapchatKit-iOS-Demo 4 | // 5 | // Created by Tanner on 7/11/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SNTableViewController.h" 10 | #import "SnapchatKit.h" 11 | 12 | #define kReuse @"reuse" 13 | 14 | @implementation SNTableViewController 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | 19 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kReuse]; 20 | } 21 | 22 | #pragma mark UITableViewDelegate 23 | 24 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 25 | return 45; 26 | } 27 | 28 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 29 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 30 | // <#XXTableViewCell#> *cell = <#self.dataSource[indexPath.row]#>; 31 | } 32 | 33 | #pragma mark UITableViewDataSource 34 | 35 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 36 | UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kReuse]; 37 | SKConversation *convo = self.dataSource[indexPath.row]; 38 | cell.textLabel.text = [NSString stringWithFormat:@"%@ — %du pending", convo.participants.firstObject, convo.pendingRecievedSnaps.count]; 39 | return cell; 40 | } 41 | 42 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 43 | return self.dataSource.count; 44 | } 45 | 46 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 47 | return 1; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SKAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKAppDelegate.m 3 | // SnapchatKit 4 | // 5 | // Created by ThePantsThief on 07/29/2015. 6 | // Copyright (c) 2015 ThePantsThief. All rights reserved. 7 | // 8 | 9 | #import "SKAppDelegate.h" 10 | #import "SNTableViewController.h" 11 | 12 | #import "SnapchatKit.h" 13 | #import "Login.h" 14 | 15 | @implementation SKAppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 18 | SNTableViewController *tableviewcontroller = [SNTableViewController new]; 19 | tableviewcontroller.title = @"SnapchatKit"; 20 | 21 | UINavigationController *nav = (UINavigationController *)self.window.rootViewController; 22 | [nav pushViewController:tableviewcontroller animated:YES]; 23 | 24 | [self trySignIn]; 25 | 26 | return YES; 27 | } 28 | 29 | - (SNTableViewController *)tableViewController { 30 | return (SNTableViewController *)([(UINavigationController *)self.window.rootViewController viewControllers].firstObject); 31 | } 32 | 33 | - (void)trySignIn { 34 | static uint16_t authenticationCount = 0; 35 | authenticationCount++; 36 | 37 | if (authenticationCount > 3) { 38 | return; 39 | } 40 | 41 | [[SKClient sharedClient] signInWithUsername:kUsername password:kPassword gmail:kGmail gpass:kGmailPassword completion:^(NSDictionary *dict, NSError *error) { 42 | if (!error) { 43 | [self tableViewController].dataSource = [SKClient sharedClient].currentSession.conversations.array; 44 | [[self tableViewController].tableView reloadData]; 45 | } else { 46 | [self trySignIn]; 47 | NSLog(@"Trying again..."); 48 | } 49 | }]; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKLocation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKLocation.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKLocation.h" 10 | #import "SKFilter.h" 11 | 12 | @implementation SKLocation 13 | 14 | - (NSString *)description { 15 | return [NSString stringWithFormat:@"<%@ num filters=%lu>\n%@", 16 | NSStringFromClass(self.class), (unsigned long)self.filters.count, self.filters]; 17 | } 18 | 19 | #pragma mark - Mantle 20 | 21 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 22 | return @{@"filters": @"filters", 23 | @"weather": @"weather", 24 | @"ourStoryAuths": @"our_story_auths", 25 | @"preCacheGeofilters": @"pre_cache_geofilters"}; 26 | } 27 | 28 | + (NSValueTransformer *)weatherJSONTransformer { return [self sk_modelArrayTransformerForClass:[SKFilter class]]; } 29 | 30 | #pragma mark - Equality 31 | 32 | - (BOOL)isEqual:(id)object { 33 | if ([object isKindOfClass:[SKLocation class]]) 34 | return [self isEqualToLocation:object]; 35 | 36 | return [super isEqual:object]; 37 | } 38 | 39 | - (BOOL)isEqualToLocation:(SKLocation *)loc { 40 | if (self.filters.count == loc.filters.count) { 41 | if (!self.filters.count) 42 | return [self.weather isEqualToDictionary:loc.weather]; 43 | else 44 | return [self.filters[0] isEqual:loc.filters[0]]; 45 | } 46 | 47 | return NO; 48 | } 49 | 50 | - (NSUInteger)hash { 51 | return [NSString stringWithFormat:@"%lu%lu%lu", 52 | (unsigned long)self.filters.count, 53 | (unsigned long)self.ourStoryAuths.count, 54 | (unsigned long)self.preCacheGeofilters.count].hash; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Example/SnapchatKit/SnapchatKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/UnknownFieldSet.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | @class PBCodedOutputStream; 19 | @class PBField; 20 | @class PBUnknownFieldSetBuilder; 21 | 22 | @interface PBUnknownFieldSet : NSObject { 23 | @private 24 | NSDictionary* fields; 25 | } 26 | 27 | @property (readonly, strong) NSDictionary* fields; 28 | 29 | + (PBUnknownFieldSet*) defaultInstance; 30 | 31 | + (PBUnknownFieldSet*) setWithFields:(NSMutableDictionary*) fields; 32 | + (PBUnknownFieldSet*) parseFromData:(NSData*) data; 33 | 34 | + (PBUnknownFieldSetBuilder*) builder; 35 | + (PBUnknownFieldSetBuilder*) builderWithUnknownFields:(PBUnknownFieldSet*) other; 36 | 37 | - (void) writeAsMessageSetTo:(PBCodedOutputStream*) output; 38 | - (void) writeToCodedOutputStream:(PBCodedOutputStream*) output; 39 | - (NSData*) data; 40 | 41 | - (SInt32) serializedSize; 42 | - (SInt32) serializedSizeAsMessageSet; 43 | 44 | - (BOOL) hasField:(SInt32) number; 45 | - (PBField*) getField:(SInt32) number; 46 | 47 | - (void) writeDescriptionTo:(NSMutableString*) output 48 | withIndent:(NSString*) indent; 49 | 50 | - (void) storeInDictionary: (NSMutableDictionary *) dic; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKCashTransaction.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKCashTransaction.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/19/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | /** Represents a cash transaction via chat. */ 12 | @interface SKCashTransaction : SKThing 13 | 14 | // SKPagination properties // 15 | 16 | @property (nonatomic, readonly) NSString *conversationIdentifier; 17 | @property (nonatomic, readonly) NSString *pagination; 18 | @property (nonatomic, readonly) NSDate *created; 19 | 20 | 21 | @property (nonatomic, readonly) SKSnapStatus status; 22 | /** The transaction amount in cents (in US). */ 23 | @property (nonatomic, readonly) NSUInteger amount; 24 | /** Example: "USD". */ 25 | @property (nonatomic, readonly) NSString *currencyCode; 26 | @property (nonatomic, readonly) BOOL invisible; 27 | @property (nonatomic, readonly) NSDate *lastUpdated; 28 | /** Example: "$2.50". */ 29 | @property (nonatomic, readonly) NSString *message; 30 | /** No idea */ 31 | @property (nonatomic, readonly) BOOL rain; 32 | 33 | @property (nonatomic, readonly) NSString *identifier; 34 | 35 | @property (nonatomic, readonly) NSString *recipient; 36 | @property (nonatomic, readonly) NSString *recipientIdentifier; 37 | @property (nonatomic, readonly) NSInteger recipientSaveVersion; 38 | @property (nonatomic, readonly) BOOL recipientSaved; 39 | @property (nonatomic, readonly) BOOL recipientViewed; 40 | 41 | @property (nonatomic, readonly) NSString *sender; 42 | @property (nonatomic, readonly) NSString *senderIdentifier; 43 | @property (nonatomic, readonly) NSInteger senderSaveVersion; 44 | @property (nonatomic, readonly) BOOL senderSaved; 45 | @property (nonatomic, readonly) BOOL senderViewed; 46 | 47 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/SKUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKUser.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKUser.h" 10 | 11 | @implementation SKUser 12 | 13 | - (NSString *)description { 14 | return [NSString stringWithFormat:@"<%@sees your stories=%d, is shared=%d, is local=%d, status=%@, username=%@>", 15 | NSStringFromClass(self.class), _canSeeCustomStories, _isSharedStory, _isLocalStory, @(self.friendStatus), self.username]; 16 | } 17 | 18 | #pragma mark - Mantle 19 | 20 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 21 | return [@{@"friendmojiString": @"friendmoji_string", 22 | @"friendmojiTypes": @"friendmoji_symbols", 23 | @"venue": @"venue", 24 | @"snapStreakCount": @"snap_streak_count", 25 | @"sharedStoryIdentifier": @"shared_story_id", 26 | @"canSeeCustomStories": @"can_see_custom_stories", 27 | @"needsLove": @"needs_love", 28 | @"isSharedStory": @"is_shared_story", 29 | @"isLocalStory": @"local_story", 30 | @"hasCustomDescription": @"has_custom_description", 31 | @"decayThumbnail": @"dont_decay_thumbnail", 32 | @"timestamp": @"ts"} mtl_dictionaryByAddingEntriesFromDictionary:[super JSONKeyPathsByPropertyKey]]; 33 | } 34 | 35 | MTLTransformPropertyDate(timestamp) 36 | MTLTransformPropertyDate(expiration) 37 | 38 | #pragma mark - Equality 39 | 40 | - (BOOL)isEqual:(id)object { 41 | if ([object isKindOfClass:[SKUser class]]) 42 | return [self isEqualToUser:object]; 43 | 44 | return [super isEqual:object]; 45 | } 46 | 47 | - (BOOL)isEqualToUser:(SKUser *)user { 48 | return [self.friendmojiString isEqualToString:user.friendmojiString] && [super isEqual:user]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ExtensionRegistry.m: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "ExtensionRegistry.h" 19 | 20 | @interface PBExtensionRegistry() 21 | @property (strong) NSDictionary* classMap; 22 | @end 23 | 24 | @implementation PBExtensionRegistry 25 | 26 | @synthesize classMap; 27 | 28 | 29 | static PBExtensionRegistry* emptyRegistry = nil; 30 | 31 | + (void) initialize { 32 | if (self == [PBExtensionRegistry class]) { 33 | emptyRegistry = [[PBExtensionRegistry alloc] initWithClassMap:[NSDictionary dictionary]]; 34 | } 35 | } 36 | 37 | 38 | - (instancetype) initWithClassMap:(NSDictionary*) map_{ 39 | if ((self = [super init])) { 40 | self.classMap = map_; 41 | } 42 | 43 | return self; 44 | } 45 | 46 | 47 | - (id) keyForClass:(Class) clazz { 48 | return NSStringFromClass(clazz); 49 | } 50 | 51 | 52 | + (PBExtensionRegistry*) emptyRegistry { 53 | return emptyRegistry; 54 | } 55 | 56 | 57 | - (id) getExtension:(Class) clazz fieldNumber:(SInt32) fieldNumber { 58 | NSDictionary* extensionMap = [classMap objectForKey:[self keyForClass:clazz]]; 59 | return [extensionMap objectForKey:[NSNumber numberWithInteger:fieldNumber]]; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/WireFormat.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | typedef enum { 19 | PBWireFormatVarint = 0, 20 | PBWireFormatFixed64 = 1, 21 | PBWireFormatLengthDelimited = 2, 22 | PBWireFormatStartGroup = 3, 23 | PBWireFormatEndGroup = 4, 24 | PBWireFormatFixed32 = 5, 25 | 26 | PBWireFormatTagTypeBits = 3, 27 | PBWireFormatTagTypeMask = 7 /* = (1 << PBWireFormatTagTypeBits) - 1*/, 28 | 29 | PBWireFormatMessageSetItem = 1, 30 | PBWireFormatMessageSetTypeId = 2, 31 | PBWireFormatMessageSetMessage = 3 32 | } PBWireFormat; 33 | 34 | SInt32 PBWireFormatMakeTag(SInt32 fieldNumber, SInt32 wireType); 35 | SInt32 PBWireFormatGetTagWireType(SInt32 tag); 36 | SInt32 PBWireFormatGetTagFieldNumber(SInt32 tag); 37 | 38 | #define PBWireFormatMessageSetItemTag (PBWireFormatMakeTag(PBWireFormatMessageSetItem, PBWireFormatStartGroup)) 39 | #define PBWireFormatMessageSetItemEndTag (PBWireFormatMakeTag(PBWireFormatMessageSetItem, PBWireFormatEndGroup)) 40 | #define PBWireFormatMessageSetTypeIdTag (PBWireFormatMakeTag(PBWireFormatMessageSetTypeId, PBWireFormatVarint)) 41 | #define PBWireFormatMessageSetMessageTag (PBWireFormatMakeTag(PBWireFormatMessageSetMessage, PBWireFormatLengthDelimited)) 42 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ExtensionField.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "WireFormat.h" 19 | 20 | @class PBCodedInputStream; 21 | @class PBCodedOutputStream; 22 | @class PBExtendableMessageBuilder; 23 | @class PBExtensionRegistry; 24 | @class PBUnknownFieldSetBuilder; 25 | 26 | @protocol PBExtensionField 27 | - (SInt32) fieldNumber; 28 | - (PBWireFormat) wireType; 29 | - (BOOL) isRepeated; 30 | - (Class) extendedClass; 31 | - (instancetype) defaultValue; 32 | 33 | - (void) mergeFromCodedInputStream:(PBCodedInputStream*) input 34 | unknownFields:(PBUnknownFieldSetBuilder*) unknownFields 35 | extensionRegistry:(PBExtensionRegistry*) extensionRegistry 36 | builder:(PBExtendableMessageBuilder*) builder 37 | tag:(SInt32) tag; 38 | - (void) writeValue:(id) value includingTagToCodedOutputStream:(PBCodedOutputStream*) output; 39 | - (SInt32) computeSerializedSizeIncludingTag:(id) value; 40 | - (void) writeDescriptionOf:(id) value 41 | to:(NSMutableString*) output 42 | withIndent:(NSString*) indent; 43 | - (void) addDictionaryEntriesOf:(id) value 44 | to:(NSMutableDictionary*) dictionary; 45 | @end 46 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/Field.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | @import Foundation; 19 | 20 | @class PBArray; 21 | @class PBAppendableArray; 22 | @class PBCodedOutputStream; 23 | 24 | @interface PBField : NSObject 25 | { 26 | @protected 27 | PBAppendableArray * _varintArray; 28 | PBAppendableArray * _fixed32Array; 29 | PBAppendableArray * _fixed64Array; 30 | NSMutableArray * _lengthDelimitedArray; 31 | NSMutableArray * _groupArray; 32 | } 33 | 34 | @property (nonatomic,strong,readonly) PBArray * varintArray; 35 | @property (nonatomic,strong,readonly) PBArray * fixed32Array; 36 | @property (nonatomic,strong,readonly) PBArray * fixed64Array; 37 | @property (nonatomic,strong,readonly) NSArray * lengthDelimitedArray; 38 | @property (nonatomic,strong,readonly) NSArray * groupArray; 39 | 40 | + (PBField *)defaultInstance; 41 | 42 | - (SInt32)getSerializedSize:(SInt32)fieldNumber; 43 | - (SInt32)getSerializedSizeAsMessageSetExtension:(SInt32)fieldNumber; 44 | 45 | - (void)writeTo:(SInt32) fieldNumber output:(PBCodedOutputStream *)output; 46 | - (void)writeAsMessageSetExtensionTo:(SInt32)fieldNumber output:(PBCodedOutputStream *)output; 47 | - (void)writeDescriptionFor:(SInt32) fieldNumber 48 | to:(NSMutableString*) output 49 | withIndent:(NSString*) indent; 50 | @end 51 | -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSData+SnapchatKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+SnapchatKit.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/5/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSData (AES) 12 | 13 | - (NSData *)AES128EncryptedDataWithKey:(NSString *)key; 14 | - (NSData *)AES128DecryptedDataWithKey:(NSString *)key; 15 | - (NSData *)AES128EncryptedDataWithKey:(NSString *)key iv:(NSString *)iv; 16 | - (NSData *)AES128DecryptedDataWithKey:(NSString *)key iv:(NSString *)iv; 17 | 18 | /** Pads data using PKCS5. blockSize defaults to 16 if given 0. */ 19 | - (NSData *)pad:(NSUInteger)blockSize; 20 | 21 | @end 22 | 23 | 24 | @interface NSData (FileFormat) 25 | 26 | @property (nonatomic, readonly) BOOL isJPEG; 27 | @property (nonatomic, readonly) BOOL isPNG; 28 | @property (nonatomic, readonly) BOOL isImage; 29 | @property (nonatomic, readonly) BOOL isMPEG4; 30 | @property (nonatomic, readonly) BOOL isMedia; 31 | @property (nonatomic, readonly) BOOL isCompressed; 32 | @property (nonatomic, readonly) NSString *appropriateFileExtension; 33 | 34 | @end 35 | 36 | @interface NSData (Encoding) 37 | @property (nonatomic, readonly) NSString *base64URLEncodedString; 38 | @property (nonatomic, readonly) NSString *MD5Hash; 39 | @property (nonatomic, readonly) NSString *hexadecimalString; 40 | @property (nonatomic, readonly) NSString *sha256Hash; 41 | @end 42 | 43 | 44 | @interface NSData (REST) 45 | + (NSData *)boundaryWithKey:(NSString *)key forStringValue:(NSString *)string; 46 | + (NSData *)boundaryWithKey:(NSString *)key forDataValue:(NSData *)data; 47 | @end 48 | 49 | 50 | @interface NSData (Blob) 51 | 52 | /** Decrypts blob data for standard images and videos. */ 53 | //- (NSData *)decryptECB; 54 | /** Encrypts blob data for standard images and videos. */ 55 | //- (NSData *)encryptECB; 56 | /** Decrypts blob data for stories. key and iv are base 64 encoded. */ 57 | - (NSData *)decryptStoryWithKey:(NSString *)key iv:(NSString *)iv; 58 | 59 | @end -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/GeneratedMessage.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "AbstractMessage.h" 19 | 20 | /** 21 | * All generated protocol message classes extend this class. This class 22 | * implements most of the Message and Builder interfaces using Java reflection. 23 | * Users can ignore this class and pretend that generated messages implement 24 | * the Message interface directly. 25 | * 26 | * @author Cyrus Najmabadi 27 | */ 28 | @class PBExtensionRegistry; 29 | @class PBCodedInputStream; 30 | @protocol GeneratedMessageProtocol 31 | + (id) parseFromData:(NSData*) data; 32 | + (id) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*)extensionRegistry; 33 | + (id) parseFromInputStream:(NSInputStream*) input; 34 | + (id) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry; 35 | + (id) parseFromCodedInputStream:(PBCodedInputStream*) input; 36 | + (id) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry; 37 | @end 38 | 39 | @interface PBGeneratedMessage : PBAbstractMessage { 40 | @private 41 | PBUnknownFieldSet* unknownFields; 42 | 43 | @protected 44 | SInt32 memoizedSerializedSize; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/MutableExtensionRegistry.m: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "MutableExtensionRegistry.h" 19 | 20 | #import "ExtensionField.h" 21 | 22 | @interface PBMutableExtensionRegistry() 23 | @property (strong) NSMutableDictionary* mutableClassMap; 24 | @end 25 | 26 | @implementation PBMutableExtensionRegistry 27 | 28 | @synthesize mutableClassMap; 29 | 30 | 31 | 32 | - (instancetype) initWithClassMap:(NSMutableDictionary*) mutableClassMap_ { 33 | if ((self = [super initWithClassMap:mutableClassMap_])) { 34 | self.mutableClassMap = mutableClassMap_; 35 | } 36 | 37 | return self; 38 | } 39 | 40 | 41 | + (PBMutableExtensionRegistry*) registry { 42 | return [[PBMutableExtensionRegistry alloc] initWithClassMap:[NSMutableDictionary dictionary]]; 43 | } 44 | 45 | 46 | - (void) addExtension:(id) extension { 47 | if (extension == nil) { 48 | return; 49 | } 50 | 51 | Class extendedClass = [extension extendedClass]; 52 | id key = [self keyForClass:extendedClass]; 53 | 54 | NSMutableDictionary* extensionMap = [classMap objectForKey:key]; 55 | if (extensionMap == nil) { 56 | extensionMap = [NSMutableDictionary dictionary]; 57 | [mutableClassMap setObject:extensionMap forKey:key]; 58 | } 59 | 60 | [extensionMap setObject:extension 61 | forKey:[NSNumber numberWithInteger:[extension fieldNumber]]]; 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/UnknownFieldSetBuilder.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "MessageBuilder.h" 19 | 20 | @class PBField; 21 | @class PBMutableField; 22 | 23 | @interface PBUnknownFieldSetBuilder : NSObject { 24 | @private 25 | NSMutableDictionary* fields; 26 | 27 | // Optimization: We keep around a builder for the last field that was 28 | // modified so that we can efficiently add to it multiple times in a 29 | // row (important when parsing an unknown repeated field). 30 | SInt32 lastFieldNumber; 31 | 32 | PBMutableField* lastField; 33 | } 34 | 35 | + (PBUnknownFieldSetBuilder*) createBuilder:(PBUnknownFieldSet*) unknownFields; 36 | 37 | - (PBUnknownFieldSet*) build; 38 | - (PBUnknownFieldSetBuilder*) mergeUnknownFields:(PBUnknownFieldSet*) other; 39 | 40 | - (PBUnknownFieldSetBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input; 41 | - (PBUnknownFieldSetBuilder*) mergeFromData:(NSData*) data; 42 | - (PBUnknownFieldSetBuilder*) mergeFromInputStream:(NSInputStream*) input; 43 | 44 | - (PBUnknownFieldSetBuilder*) mergeVarintField:(SInt32) number value:(SInt32) value; 45 | 46 | - (BOOL) mergeFieldFrom:(SInt32) tag input:(PBCodedInputStream*) input; 47 | 48 | - (PBUnknownFieldSetBuilder*) addField:(PBField*) field forNumber:(SInt32) number; 49 | 50 | - (PBUnknownFieldSetBuilder*) clear; 51 | - (PBUnknownFieldSetBuilder*) mergeField:(PBField*) field forNumber:(SInt32) number; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSString+SnapchatKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Encoding.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/5/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface NSString (Util) 13 | 14 | /// Joins other strings into a single string with the receiver in between each. 15 | - (NSString *)join:(NSArray *)otherStrings; 16 | 17 | @end 18 | 19 | @interface NSString (Encoding) 20 | 21 | @property (nonatomic, readonly) NSString *base64Encoded; 22 | @property (nonatomic, readonly) NSString *base64URLEncoded; 23 | @property (nonatomic, readonly) NSString *base64Decoded; 24 | @property (nonatomic, readonly) NSData *base64DecodedData; 25 | 26 | @property (nonatomic, readonly) NSString *MD5Hash; 27 | @property (nonatomic, readonly) NSString *sha256Hash; 28 | @property (nonatomic, readonly) NSData *sha256HashData; 29 | 30 | 31 | /** Implementation of Snapchat's hashing algorithm. */ 32 | + (NSString *)hashSC:(NSData *)first and:(NSData *)second; 33 | + (NSString *)hashSCString:(NSString *)first and:(NSString *)second; 34 | 35 | + (NSData *)hashHMac:(NSString *)data key:(NSString *)key; 36 | + (NSString *)hashHMacToString:(NSString *)data key:(NSString *)key; 37 | 38 | @end 39 | 40 | 41 | @interface NSString (REST) 42 | 43 | + (NSString *)timestamp; 44 | + (NSString *)timestampInSeconds; 45 | + (NSString *)timestampFrom:(NSDate *)date; 46 | + (NSString *)queryStringWithParams:(NSDictionary *)params; 47 | + (NSString *)queryStringWithParams:(NSDictionary *)params URLEscapeValues:(BOOL)escapeValues; 48 | 49 | @end 50 | 51 | 52 | @interface NSString (Regex) 53 | @property (nonatomic, readonly) NSString *textFromHTML; 54 | - (NSString *)matchGroupAtIndex:(NSUInteger)idx forRegex:(NSString *)regex; 55 | - (NSArray *)allMatchesForRegex:(NSString *)regex; 56 | - (NSString *)stringByReplacingMatchesForRegex:(NSString *)regex withString:(NSString *)replacement; 57 | @end 58 | 59 | @interface NSString (Snapchat) 60 | + (NSString *)SCIdentifierWith:(NSString *)first and:(NSString *)second; 61 | @end 62 | 63 | extern NSString * SKMediaIdentifier(NSString *sender); 64 | extern NSString * SKUniqueIdentifier(); -------------------------------------------------------------------------------- /Pod/Classes/Model/SKConversationState.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKConversationState.m 3 | // Pods 4 | // 5 | // Created by Tanner on 1/6/16. 6 | // 7 | // 8 | 9 | #import "SKConversationState.h" 10 | 11 | @implementation SKConversationState 12 | 13 | + (instancetype)state:(NSDictionary *)json recipient:(NSString *)recipient { 14 | return [[self alloc] initWithDictionary:json recipient:recipient]; 15 | } 16 | 17 | - (id)initWithDictionary:(NSDictionary *)json recipient:(NSString *)recipient { 18 | NSParameterAssert(recipient); 19 | 20 | self = [super initWithDictionary:json]; 21 | if (self) { 22 | NSDictionary *releases = json[@"user_chat_releases"]; 23 | NSDictionary *sequences = json[@"user_sequences"]; 24 | 25 | // Case for empty conversations 26 | if (!sequences.allKeys.count) 27 | return self; 28 | 29 | NSInteger idx = [sequences.allKeys indexOfObject:recipient]; 30 | NSString *sender; 31 | if (idx == 0) 32 | sender = releases.allKeys.firstObject; 33 | else 34 | sender = sequences.allKeys.firstObject; 35 | 36 | // Actual sent values, not percieved values 37 | _recipientSentCount = [sequences[recipient] integerValue]; 38 | _senderSentCount = [sequences[sender] integerValue]; 39 | // Unread = actual sent - percieved sent 40 | _recipientUnreadCount = _senderSentCount - [releases[recipient][sender] integerValue]; 41 | _senderUnreadCount = _recipientSentCount - [releases[sender][recipient] integerValue]; 42 | } 43 | 44 | return self; 45 | } 46 | 47 | - (NSString *)description { 48 | return [NSString stringWithFormat:@"<%@ your unread=%@, sent=%@, sender unread=%@, sent=%@>", 49 | NSStringFromClass(self.class), @(_recipientUnreadCount), @(_recipientSentCount), @(_senderUnreadCount), @(_senderSentCount)]; 50 | } 51 | 52 | + (NSArray *)ignoredJSONKeyPathPrefixes { 53 | static NSArray *ignored = nil; 54 | static dispatch_once_t onceToken; 55 | dispatch_once(&onceToken, ^{ 56 | ignored = @[@"user_chat_releases", @"user_sequences", @"user_snap_releases"]; 57 | }); 58 | 59 | return ignored; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnap.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnap.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/19/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SKThing.h" 11 | @class SKBlob; 12 | 13 | /** Not a counterpart of the \c SKSentSnap class. */ 14 | @interface SKSnap : SKThing 15 | 16 | /** nil if snap is "outgoing". */ 17 | @property (nonatomic, readonly) NSString *sender; 18 | /** nil if snap is "incoming". */ 19 | @property (nonatomic, readonly) NSString *recipient; 20 | @property (nonatomic, readonly) NSString *identifier; 21 | /** Not sure what this is for. Sometimes nil. */ 22 | @property (nonatomic, readonly) NSString *conversationIdentifier; 23 | @property (nonatomic, readonly) SKMediaKind mediaKind; 24 | @property (nonatomic, readonly) SKSnapStatus status; 25 | @property (nonatomic, readonly) BOOL isOutgoing; 26 | @property (nonatomic, readonly) NSUInteger screenshots; 27 | /** Integer time. _mediaTimer rounded down. 0 if snap is "outgoing". */ 28 | @property (nonatomic, readonly) NSUInteger timer; 29 | /** Actual lenth of the video, or the same as _timer for images. 0.f is snap is "outgoing". */ 30 | @property (nonatomic, readonly) CGFloat mediaTimer; 31 | @property (nonatomic, readonly) NSDate *sentDate; 32 | /** Undocumented. */ 33 | @property (nonatomic, readonly) NSDate *timestamp; 34 | @property (nonatomic, readonly) NSString *esIdentifier; 35 | @property (nonatomic, readonly) id mo; 36 | 37 | /** Whether the snap is compressed or not. */ 38 | @property (nonatomic, readonly) BOOL zipped; 39 | /** \c nil until you call \c load: */ 40 | @property (nonatomic, readonly) SKBlob *blob; 41 | 42 | @end 43 | 44 | 45 | @interface SKSnap (SKClient) 46 | /** Loads the blob for the story. 47 | @discussion If successful, the \c blob property of the original \c SKSnap will contain the snap's blob data. 48 | @param completion Takes an error, if any. */ 49 | - (void)load:(ErrorBlock)completion; 50 | /** @return If \c blob is \c nil, returns nil. For images: \c {identifier}.jpg, for videos: \c {identifier}.mp4, and for videos with an overlay just {identifier} */ 51 | @property (nonatomic, readonly) NSString *suggestedFilename; 52 | 53 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryCollection.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryCollection.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SKThing.h" 11 | 12 | @interface SKStoryCollection : SKThing 13 | 14 | /** The username of the user associated with this story collection. */ 15 | @property (nonatomic, readonly) NSString *username; 16 | /** Whether this story contains explicit content. */ 17 | @property (nonatomic, readonly) BOOL matureContent; 18 | /** An array of \c SKStory objects. */ 19 | @property (nonatomic, readonly) NSArray *stories; 20 | 21 | 22 | /** The display name of the shared story. @note Only applies to shared stories. */ 23 | @property (nonatomic, readonly) NSString *displayName; 24 | /** The identifier of the shared story. @note Only applies to shared stories. */ 25 | @property (nonatomic, readonly) NSString *sharedIdentifier; 26 | /** Whether the shared story is local or not. @note Only applies to shared stories. */ 27 | @property (nonatomic, readonly) BOOL isLocal; 28 | /** Whether the shared story has a custom description. */ 29 | @property (nonatomic, readonly) BOOL hasCustomDescription; 30 | /** Whether the story supports the "story explorer" feature. */ 31 | @property (nonatomic, readonly) BOOL allowStoryExplorer; 32 | 33 | /** The thumbnail for the viewed state of the story. @note Only applies to shared stories. */ 34 | @property (nonatomic, readonly) NSURL *viewedThumbnail; 35 | /** The thumbnail for the unviewed state of the story. @note Only applies to shared stories. */ 36 | @property (nonatomic, readonly) NSURL *unviewedThumbnail; 37 | /** @note Only applies to shared stories. */ 38 | @property (nonatomic, readonly) BOOL viewedThumbNeedsAuth; 39 | /** @note Only applies to shared stories. */ 40 | @property (nonatomic, readonly) BOOL unviewedThumbNeedsAuth; 41 | 42 | /** @note Only applies to shared stories. */ 43 | @property (nonatomic, readonly) NSDictionary *adPlacementData; 44 | 45 | /** @discussion The API doesn't tell you whether an entire story is shared, 46 | so this method checks if the first object in it's \c stories property is \c shared. */ 47 | @property (nonatomic, readonly) BOOL isSharedStory; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ConcreteExtensionField.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "ExtensionField.h" 19 | 20 | typedef enum { 21 | PBExtensionTypeBool, 22 | PBExtensionTypeFixed32, 23 | PBExtensionTypeSFixed32, 24 | PBExtensionTypeFloat, 25 | PBExtensionTypeFixed64, 26 | PBExtensionTypeSFixed64, 27 | PBExtensionTypeDouble, 28 | PBExtensionTypeInt32, 29 | PBExtensionTypeInt64, 30 | PBExtensionTypeSInt32, 31 | PBExtensionTypeSInt64, 32 | PBExtensionTypeUInt32, 33 | PBExtensionTypeUInt64, 34 | PBExtensionTypeBytes, 35 | PBExtensionTypeString, 36 | PBExtensionTypeMessage, 37 | PBExtensionTypeGroup, 38 | PBExtensionTypeEnum 39 | } PBExtensionType; 40 | 41 | @interface PBConcreteExtensionField : NSObject { 42 | @private 43 | PBExtensionType type; 44 | 45 | Class extendedClass; 46 | SInt32 fieldNumber; 47 | id defaultValue; 48 | 49 | Class messageOrGroupClass; 50 | 51 | BOOL isRepeated; 52 | BOOL isPacked; 53 | BOOL isMessageSetWireFormat; 54 | } 55 | 56 | + (PBConcreteExtensionField*) extensionWithType:(PBExtensionType) type 57 | extendedClass:(Class) extendedClass 58 | fieldNumber:(SInt32) fieldNumber 59 | defaultValue:(id) defaultValue 60 | messageOrGroupClass:(Class) messageOrGroupClass 61 | isRepeated:(BOOL) isRepeated 62 | isPacked:(BOOL) isPacked 63 | isMessageSetWireFormat:(BOOL) isMessageSetWireFormat; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSimpleUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKSimpleUser.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKSimpleUser.h" 10 | 11 | 12 | @implementation SKSimpleUser 13 | 14 | - (id)initWithDictionary:(NSDictionary *)json error:(NSError *__autoreleasing *)error { 15 | self = [super initWithDictionary:json error:error]; 16 | if (self) { 17 | if (!_displayName.length) _displayName = nil; 18 | } 19 | 20 | return self; 21 | } 22 | 23 | - (id)initWithDictionary:(NSDictionary *)json { 24 | // API debugging 25 | if (![json[@"direction"] isEqualToString:@"OUTGOING"] && ![json[@"direction"] isEqualToString:@"INCOMING"]) 26 | SKLog(@"SKSimpleUser new 'direction': %@", json[@"direction"]); 27 | 28 | return [super initWithDictionary:json]; 29 | } 30 | 31 | - (NSString *)description { 32 | return [NSString stringWithFormat:@"<%@ username=%@, displayn=%@, incoming=%d>", 33 | NSStringFromClass(self.class), _username, _displayName, _addedIncoming]; 34 | } 35 | 36 | #pragma mark - Mantle 37 | 38 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 39 | return @{@"username": @"name", 40 | @"displayName": @"display", 41 | @"userIdentifier": @"user_id", 42 | @"addedIncoming": @"direction", 43 | @"ignoredLink": @"ignored_link", 44 | @"expiration": @"expiration", 45 | @"addedBack": @"reverse_ts", 46 | @"friendStatus": @"type"}; 47 | } 48 | 49 | + (NSValueTransformer *)addedIncomingJSONTransformer { 50 | return [NSValueTransformer mtl_valueMappingTransformerWithDictionary:@{@"INCOMING": @YES, @"OUTGOING": @NO} defaultValue:@NO reverseDefaultValue:@"__unspecified"]; 51 | } 52 | 53 | MTLTransformPropertyDate(expiration) 54 | MTLTransformPropertyDate(addedBack) 55 | 56 | #pragma mark - Equality 57 | 58 | - (BOOL)isEqual:(id)object { 59 | if ([object isKindOfClass:[SKSimpleUser class]]) 60 | return [self isEqualToSimpleUser:object]; 61 | 62 | return [super isEqual:object]; 63 | } 64 | 65 | - (BOOL)isEqualToSimpleUser:(SKSimpleUser *)user { 66 | return [_username isEqualToString:user.username]; 67 | } 68 | 69 | - (NSUInteger)hash { 70 | return _username.hash; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKThing.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKThing.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SnapchatKit-Constants.h" 11 | #import "Mantle.h" 12 | 13 | // Mantle macros // 14 | 15 | // string to URL transform 16 | #define MTLTransformPropertyURL(property) + (NSValueTransformer *) property##JSONTransformer { \ 17 | return [self sk_urlTransformer]; } 18 | 19 | // ts to NSDate transform 20 | #define MTLTransformPropertyDate(property) + (NSValueTransformer *) property##JSONTransformer { \ 21 | return [self sk_dateTransformer]; } 22 | 23 | /// The root class of most classes in this framework. 24 | @interface SKThing : MTLModel 25 | 26 | - (id)initWithDictionary:(NSDictionary *)json; 27 | 28 | /// Transforms Snapchat's UTC timestamp floats into \c NSDate. 29 | + (NSValueTransformer *)sk_dateTransformer; 30 | /// Transforms strings into NSURL objects. 31 | + (NSValueTransformer *)sk_urlTransformer; 32 | /// Transforms strings from "ON" and "OFF" to YES and NO. 33 | + (NSValueTransformer *)sk_onOffTransformer; 34 | /// Transforms an array of dictionaries into an array of model objects of class \c cls. 35 | + (NSValueTransformer *)sk_modelArrayTransformerForClass:(Class)cls; 36 | /// Transforms an array of dictionaries into an ordered set of model objects of class \c cls. 37 | + (NSValueTransformer *)sk_modelMutableOrderedSetTransformerForClass:(Class)cls; 38 | 39 | /// For API debugging purposes. 40 | + (NSArray *)knownJSONKeys; 41 | /// Calculated once when first accessed, using \c knownJSONKeys. 42 | + (NSArray *)unknownJSONKeys; 43 | + (NSDictionary *)allSubclassesUnknownJSONKeys; 44 | /// Used to filter out unused JSON keys I don't want to use. 45 | + (NSArray *)ignoredJSONKeyPathPrefixes; 46 | 47 | /// Transforms \c jsons to an array of model objects of class \c cls. 48 | + (NSArray *)transformJSONArray:(NSArray *)jsons toModelsOfClass:(Class)cls; 49 | 50 | /// Calls into [MTLJSONAdapter JSONDictionaryFromModel:foo error:nil] 51 | @property (readonly) NSDictionary *JSONDictionary; 52 | 53 | @end 54 | 55 | 56 | @protocol SKPagination 57 | @property (nonatomic, readonly) NSString *pagination; 58 | @optional 59 | @property (nonatomic, readonly) NSDate *created; 60 | @property (nonatomic, readonly) NSString *conversationIdentifier; 61 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnapResponse.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnapResponse.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/29/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKSnapResponse.h" 10 | 11 | 12 | @implementation SKSentSnap 13 | 14 | - (id)initWithDictionary:(NSDictionary *)json sender:(NSString *)sender { 15 | self = [super initWithDictionary:json]; 16 | if (self) { 17 | _sender = sender; 18 | } 19 | 20 | return self; 21 | } 22 | 23 | /// Do not use 24 | 25 | - (id)initWithDictionary:(NSDictionary *)json error:(NSError *__autoreleasing *)error { [NSException raise:NSInternalInconsistencyException format:@"Use -initWithDictionary:sender:"]; return nil; } 26 | 27 | - (NSString *)description { 28 | return [NSString stringWithFormat:@"<%@ sender=%@, id=%@, ts=%@>", 29 | NSStringFromClass(self.class), _sender, _identifier, @(_timestamp.timeIntervalSince1970).stringValue]; 30 | } 31 | 32 | #pragma mark - Mantle 33 | 34 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 35 | return @{@"identifier": @"id", 36 | @"timestamp": @"timestamp"}; 37 | } 38 | 39 | MTLTransformPropertyDate(timestamp) 40 | 41 | @end 42 | 43 | 44 | @implementation SKSnapResponse 45 | 46 | - (NSString *)description { 47 | return [NSString stringWithFormat:@"<%@ success=%d> Snaps:\n%@", 48 | NSStringFromClass(self.class), _success, _sentSnaps]; 49 | } 50 | 51 | #pragma mark - Mantle 52 | 53 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 54 | return @{@"success": @"snap_response.success", 55 | @"sentSnaps": @"snap_response.snaps"}; 56 | } 57 | 58 | + (NSValueTransformer *)sentSnapsJSONTransformer { 59 | return [MTLValueTransformer transformerUsingForwardBlock:^id(NSDictionary *snaps, BOOL *success, NSError *__autoreleasing *error) { 60 | NSMutableArray *temp = [NSMutableArray array]; 61 | for (NSString *sender in snaps.allKeys) 62 | [temp addObject:[[SKSentSnap alloc] initWithDictionary:snaps[sender] sender:sender]]; 63 | return temp.copy; 64 | } reverseBlock:^id(NSArray *snaps, BOOL *success, NSError *__autoreleasing *error) { 65 | NSMutableDictionary *json = [NSMutableDictionary dictionary]; 66 | for (SKSentSnap *snap in snaps) 67 | json[snap.sender] = snap.JSONDictionary; 68 | return json.copy; 69 | }]; 70 | } 71 | 72 | @end -------------------------------------------------------------------------------- /Pod/Classes/Model/SKFilter.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKFilter.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKFilter.h" 10 | 11 | #import "NSArray+SnapchatKit.h" 12 | #import 13 | 14 | @implementation SKFilter 15 | 16 | - (NSString *)description { 17 | return [NSString stringWithFormat:@"<%@ dynamic=%d, sponsored=%d, priority=%ld image=%@>", 18 | NSStringFromClass(self.class), self.isDynamic, self.isSponsored, (long)self.priority, self.imageURL.absoluteString]; 19 | } 20 | 21 | #pragma mark - Mantle 22 | 23 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 24 | return @{@"identifier": @"filter_id", 25 | @"priority": @"priority", 26 | @"hideSponsoredSlug": @"hide_sponsored_slug", 27 | @"imageURL": @"image", 28 | @"isDynamic": @"is_dynamic_geofilter", 29 | @"isSponsored": @"is_sponsored", 30 | @"position": @"position", 31 | @"prepositioned": @"prepositioned", 32 | @"prepositionedImageURL": @"prepositioned_image", 33 | @"geofenceIdentifier": @"geofence.id", 34 | @"coordinates": @"geofence.coordinates"}; 35 | } 36 | 37 | MTLTransformPropertyURL(imageURL) 38 | MTLTransformPropertyURL(prepositionedImageURL) 39 | 40 | + (NSValueTransformer *)coordinatesJSONTransformer { 41 | return [MTLValueTransformer transformerUsingForwardBlock:^id(NSArray *coords, BOOL *success, NSError *__autoreleasing *error) { 42 | NSMutableArray *locations = [NSMutableArray array]; 43 | for (NSDictionary *loc in coords) 44 | [locations addObject:[[CLLocation alloc] initWithLatitude:[loc[@"lat"] doubleValue] longitude:[loc[@"long"] doubleValue]]]; 45 | return locations.copy; 46 | } reverseBlock:^id(NSArray *locations, BOOL *success, NSError *__autoreleasing *error) { 47 | return locations.dictionaryValues; 48 | }]; 49 | } 50 | 51 | #pragma mark - Equality 52 | 53 | - (BOOL)isEqual:(id)object { 54 | if ([object isKindOfClass:[SKFilter class]]) 55 | return [self isEqualToFilter:object]; 56 | 57 | return [super isEqual:object]; 58 | } 59 | 60 | - (BOOL)isEqualToFilter:(SKFilter *)filter { 61 | return [filter.identifier isEqualToString:self.identifier]; 62 | } 63 | 64 | - (NSUInteger)hash { 65 | return self.identifier.hash; 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/RingBuffer.m: -------------------------------------------------------------------------------- 1 | #import "RingBuffer.h" 2 | 3 | @implementation RingBuffer 4 | 5 | - (instancetype)initWithData:(NSMutableData*)data { 6 | if ((self = [super init])) { 7 | buffer = data; 8 | } 9 | return self; 10 | } 11 | 12 | 13 | - (UInt32)freeSpace { 14 | return (UInt32)(position < tail ? tail - position : (buffer.length - position) + tail) - (tail ? 1 : 0); 15 | } 16 | 17 | 18 | - (BOOL)appendByte:(uint8_t)byte { 19 | if (self.freeSpace < 1) return NO; 20 | ((uint8_t*)buffer.mutableBytes)[position++] = byte; 21 | return YES; 22 | } 23 | 24 | 25 | - (SInt32)appendData:(const NSData*)value offset:(SInt32)offset length:(SInt32)length { 26 | SInt32 totalWritten = 0; 27 | const uint8_t *input = value.bytes; 28 | uint8_t *data = buffer.mutableBytes; 29 | 30 | if (position >= tail) { 31 | totalWritten = MIN((UInt32)buffer.length - position, length); 32 | memcpy(data + position, input + offset, totalWritten); 33 | position += totalWritten; 34 | if (totalWritten == length) return length; 35 | length -= totalWritten; 36 | offset += totalWritten; 37 | } 38 | 39 | UInt32 freeSpace = self.freeSpace; 40 | if (!freeSpace) return totalWritten; 41 | 42 | if (position == buffer.length) { 43 | position = 0; 44 | } 45 | 46 | // position < tail 47 | SInt32 written = MIN(freeSpace, length); 48 | memcpy(data + position, input + offset, written); 49 | position += written; 50 | totalWritten += written; 51 | 52 | return totalWritten; 53 | } 54 | 55 | 56 | - (SInt32)flushToOutputStream:(NSOutputStream*)stream { 57 | SInt32 totalWritten = 0; 58 | const uint8_t *data = buffer.bytes; 59 | 60 | if (tail > position) { 61 | SInt32 written = (SInt32)[stream write:data + tail maxLength:buffer.length - tail]; 62 | if (written <= 0) return totalWritten; 63 | totalWritten += written; 64 | tail += written; 65 | if (tail == buffer.length) { 66 | tail = 0; 67 | } 68 | } 69 | 70 | if (tail < position) { 71 | SInt32 written = (SInt32)[stream write:data + tail maxLength:position - tail]; 72 | if (written <= 0) return totalWritten; 73 | totalWritten += written; 74 | tail += written; 75 | } 76 | 77 | if (tail == position) { 78 | tail = position = 0; 79 | } 80 | 81 | if (position == buffer.length && tail > 0) { 82 | position = 0; 83 | } 84 | 85 | if (tail == buffer.length) { 86 | tail = 0; 87 | } 88 | 89 | return totalWritten; 90 | } 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStoryCollection.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKStoryCollection.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKStoryCollection.h" 10 | #import "SKStory.h" 11 | 12 | @implementation SKStoryCollection 13 | 14 | - (NSString *)description { 15 | return [NSString stringWithFormat:@"<%@ username=%@, NSFW=%d count=%lu> stories=%@", 16 | NSStringFromClass(self.class), self.username, self.matureContent, (unsigned long)self.stories.count, self.stories]; 17 | } 18 | 19 | #pragma mark - Mantle 20 | 21 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 22 | return @{@"username": @"username", 23 | @"matureContent": @"mature_content", 24 | @"adPlacementData": @"ad_placement_metadata", 25 | @"displayName": @"display_name", 26 | @"sharedIdentifier": @"shared_id", 27 | @"isLocal": @"is_local", 28 | @"viewedThumbnail": @"thumbnails.viewed.url", 29 | @"unviewedThumbnail": @"thumbnails.unviewed.url", 30 | @"viewedThumbNeedsAuth": @"thumbnails.viewed.needs_auth", 31 | @"unviewedThumbNeedsAuth": @"thumbnails.unviewed.needs_auth", 32 | @"stories": @"stories", 33 | @"hasCustomDescription": @"has_custom_description", 34 | @"allowStoryExplorer": @"allow_story_explorer"}; 35 | } 36 | 37 | + (NSArray *)ignoredJSONKeyPathPrefixes { 38 | static NSArray *ignored = nil; 39 | static dispatch_once_t onceToken; 40 | dispatch_once(&onceToken, ^{ 41 | ignored = @[@"ad_placement_metadata"]; 42 | }); 43 | 44 | return ignored; 45 | } 46 | 47 | MTLTransformPropertyURL(viewedThumbnail) 48 | MTLTransformPropertyURL(unviewedThumbnail) 49 | 50 | + (NSValueTransformer *)storiesJSONTransformer { return [self sk_modelArrayTransformerForClass:[SKStory class]]; } 51 | 52 | #pragma mark - Equality 53 | 54 | - (BOOL)isEqual:(id)object { 55 | if ([object isKindOfClass:[SKStoryCollection class]]) 56 | return [self isEqualToStoryCollection:object]; 57 | 58 | return [super isEqual:object]; 59 | } 60 | 61 | - (BOOL)isEqualToStoryCollection:(SKStoryCollection *)collection { 62 | return [self.username isEqualToString:collection.username]; 63 | } 64 | 65 | - (NSUInteger)hash { 66 | return self.username.hash; 67 | } 68 | 69 | - (BOOL)isSharedStory { 70 | return [self.stories[0] shared]; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/SnapchatKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/Message.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | @class PBCodedOutputStream; 19 | @class PBUnknownFieldSet; 20 | @protocol PBMessageBuilder; 21 | 22 | /** 23 | * Abstract interface implemented by Protocol Message objects. 24 | * 25 | * @author Cyrus Najmabadi 26 | */ 27 | @protocol PBMessage 28 | /** 29 | * Get an instance of the type with all fields set to their default values. 30 | * This may or may not be a singleton. This differs from the 31 | * {@code getDefaultInstance()} method of generated message classes in that 32 | * this method is an abstract method of the {@code Message} interface 33 | * whereas {@code getDefaultInstance()} is a static method of a specific 34 | * class. They return the same thing. 35 | */ 36 | - (id) defaultInstance; 37 | 38 | /** 39 | * Get the {@code UnknownFieldSet} 40 | */ 41 | - (PBUnknownFieldSet*) unknownFields; 42 | 43 | /** 44 | * Get the number of bytes required to encode this message. The result 45 | * is only computed on the first call and memoized after that. 46 | */ 47 | - (SInt32) serializedSize; 48 | 49 | /** 50 | * Returns true if all required fields in the message and all embedded 51 | * messages are set, false otherwise. 52 | */ 53 | - (BOOL) isInitialized; 54 | 55 | /** 56 | * Serializes the message and writes it to {@code output}. This does not 57 | * flush or close the stream. 58 | */ 59 | - (void) writeToCodedOutputStream:(PBCodedOutputStream*) output; 60 | - (void) writeToOutputStream:(NSOutputStream*) output; 61 | 62 | /** 63 | * Serializes the message to a {@code ByteString} and returns it. This is 64 | * just a trivial wrapper around 65 | * {@link #writeTo(CodedOutputStream)}. 66 | */ 67 | - (NSData*) data; 68 | 69 | /** 70 | * Constructs a new builder for a message of the same type as this message. 71 | */ 72 | - (id) builder; 73 | 74 | /** 75 | * Constructs a builder initialized with the current message. Use this to 76 | * derive a new message from the current one. 77 | */ 78 | - (id) toBuilder; 79 | 80 | /** 81 | * Returns a string description of the message. 82 | */ 83 | - (NSString*) description; 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ExtendableMessageBuilder.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "GeneratedMessageBuilder.h" 19 | 20 | #import "ExtensionField.h" 21 | 22 | @class PBExtendableMessage; 23 | 24 | /** 25 | * Generated message builders for message types that contain extension ranges 26 | * subclass this. 27 | * 28 | *

This class implements type-safe accessors for extensions. They 29 | * implement all the same operations that you can do with normal fields -- 30 | * e.g. "get", "set", and "add" -- but for extensions. The extensions are 31 | * identified using instances of the class {@link GeneratedExtension}; the 32 | * protocol compiler generates a static instance of this class for every 33 | * extension in its input. Through the magic of generics, all is made 34 | * type-safe. 35 | * 36 | *

For example, imagine you have the {@code .proto} file: 37 | * 38 | *

39 |  * option java_class = "MyProto";
40 |  *
41 |  * message Foo {
42 |  *   extensions 1000 to max;
43 |  * }
44 |  *
45 |  * extend Foo {
46 |  *   optional int32 bar;
47 |  * }
48 |  * 
49 | * 50 | *

Then you might write code like: 51 | * 52 | *

53 |  * MyProto.Foo foo =
54 |  *   MyProto.Foo.newBuilder()
55 |  *     .setExtension(MyProto.bar, 123)
56 |  *     .build();
57 |  * 
58 | * 59 | *

See also {@link ExtendableMessage}. 60 | */ 61 | @interface PBExtendableMessageBuilder : PBGeneratedMessageBuilder { 62 | } 63 | 64 | - (id) getExtension:(id) extension; 65 | - (BOOL) hasExtension:(id) extension; 66 | - (PBExtendableMessageBuilder*) setExtension:(id) extension 67 | value:(id) value; 68 | - (PBExtendableMessageBuilder*) addExtension:(id) extension 69 | value:(id) value; 70 | - (PBExtendableMessageBuilder*) setExtension:(id) extension 71 | index:(SInt32) index 72 | value:(id) value; 73 | - (PBExtendableMessageBuilder*) clearExtension:(id) extension; 74 | 75 | /* @protected */ 76 | - (void) mergeExtensionFields:(PBExtendableMessage*) other; 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKMessage.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/19/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKThing.h" 10 | 11 | typedef NS_ENUM(NSUInteger, SKMessageKind) 12 | { 13 | SKMessageKindText = 1, 14 | SKMessageKindMedia, 15 | SKMessageKindDiscoverShared, 16 | SKMessageKindStoryReply 17 | }; 18 | 19 | extern SKMessageKind SKMessageKindFromString(NSString *messageKindString); 20 | 21 | @interface SKMessage : SKThing 22 | 23 | // SKPagination 24 | @property (nonatomic, readonly) NSString *pagination; 25 | @property (nonatomic, readonly) NSString *conversationIdentifier; 26 | @property (nonatomic, readonly) NSDate *created; 27 | 28 | /** Use this property to mark a message as read. */ 29 | @property (nonatomic, readonly) NSString *identifier; 30 | @property (nonatomic, readonly) NSString *messageIdentifier; 31 | @property (nonatomic, readonly) SKMessageKind messageKind; 32 | 33 | /** \c nil if \c messageKind is \c SKMessageKindMedia. */ 34 | @property (nonatomic, readonly) NSString *text; 35 | 36 | /** \c nil if \c messageKind is \c SKMessageKindText. */ 37 | @property (nonatomic, readonly) NSString *mediaIdentifier; 38 | 39 | #ifndef UIKIT_EXTERN 40 | /** \c 0 if \c messageKind is \c SKMessageKindText. */ 41 | @property (nonatomic, readonly) NSInteger mediaWidth; 42 | /** \c 0 if \c messageKind is \c SKMessageKindText. */ 43 | @property (nonatomic, readonly) NSInteger mediaHeight; 44 | #else 45 | /** \c {0,0} if \c messageKind is \c SKMessageKindText. */ 46 | @property (nonatomic, readonly) CGSize mediaSize; 47 | #endif 48 | 49 | /** \c nil if \c messageKind is \c SKMessageKindText. */ 50 | @property (nonatomic, readonly) NSString *mediaIV; 51 | /** \c nil if \c messageKind is \c SKMessageKindText. */ 52 | @property (nonatomic, readonly) NSString *mediaKey; 53 | /** i.e. "VIDEO" or "IMAGE" */ 54 | @property (nonatomic, readonly) NSString *mediaType; 55 | /** The identifier of the replied-to story. \c nil unless \c messageKind is \c SKMessageKindStoryReply. */ 56 | @property (nonatomic, readonly) NSString *storyIdentifier; 57 | /** Whether the replied-to story is zipped. */ 58 | @property (nonatomic, readonly) BOOL zipped; 59 | 60 | /** Array of usernames. */ 61 | @property (nonatomic, readonly) NSArray *recipients; 62 | @property (nonatomic, readonly) NSString *sender; 63 | 64 | /** The position of this message in the conversation. i.e. 1 if it is the first message. */ 65 | @property (nonatomic, readonly) NSUInteger index; 66 | 67 | /** Keys for each participant mapped to dictionaries with keys "saved" and "version". */ 68 | @property (nonatomic, readonly) NSDictionary *savedState; 69 | 70 | /** So far, it's just "chat_message". Odd. */ 71 | @property (nonatomic, readonly) NSString *type; 72 | 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKSnap.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKSnap.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/19/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKSnap.h" 10 | #import "SKBlob.h" 11 | #import "SKClient+Snaps.h" 12 | 13 | @implementation SKSnap 14 | 15 | - (id)initWithDictionary:(NSDictionary *)json error:(NSError *__autoreleasing *)error { 16 | if (!json.allKeys.count) return nil; 17 | 18 | self = [super initWithDictionary:json error:error]; 19 | if (self) { 20 | _isOutgoing = [_identifier hasSuffix:@"s"]; 21 | } 22 | 23 | return self; 24 | } 25 | 26 | - (NSString *)description { 27 | return [NSString stringWithFormat:@"<%@ to/from=%@, kind=%lu, duration=%f, screenshots=%lu>", 28 | NSStringFromClass(self.class), self.sender?:self.recipient, (long)self.mediaKind, self.mediaTimer, (unsigned long)self.screenshots]; 29 | } 30 | 31 | #pragma mark - Mantle 32 | 33 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 34 | return @{@"sender": @"sn", 35 | @"recipient": @"rp", 36 | @"identifier": @"id", 37 | @"conversationIdentifier": @"c_id", 38 | @"mediaKind": @"m", 39 | @"status": @"st", 40 | @"screenshots": @"c", 41 | @"timer": @"t", 42 | @"mediaTimer": @"timer", 43 | @"sentDate": @"sts", 44 | @"timestamp": @"ts", 45 | @"zipped": @"zipped", 46 | @"esIdentifier": @"es_id", 47 | @"mo": @"mo"}; 48 | } 49 | 50 | MTLTransformPropertyDate(sentDate) 51 | MTLTransformPropertyDate(timestamp) 52 | 53 | #pragma mark - Equality 54 | 55 | - (BOOL)isEqual:(id)object { 56 | if ([object isKindOfClass:[SKSnap class]]) 57 | return [self isEqualToSnap:object]; 58 | 59 | return [super isEqual:object]; 60 | } 61 | 62 | - (BOOL)isEqualToSnap:(SKSnap *)snap { 63 | return [self.identifier isEqualToString:snap.identifier]; 64 | } 65 | 66 | - (NSUInteger)hash { 67 | return self.identifier.hash; 68 | } 69 | 70 | @end 71 | 72 | 73 | @implementation SKSnap (SKClient) 74 | 75 | - (void)load:(ErrorBlock)completion { 76 | NSParameterAssert(completion); 77 | [[SKClient sharedClient] loadSnap:self completion:^(SKBlob *blob, NSError *error) { 78 | if (!error) { 79 | _blob = blob; 80 | completion(nil); 81 | } else { 82 | completion(error); 83 | } 84 | }]; 85 | } 86 | 87 | - (NSString *)suggestedFilename { 88 | if (!self.blob) 89 | return nil; 90 | return [NSString stringWithFormat:@"%@~%@", self.sender, self.identifier]; 91 | // if (self.blob.isImage) 92 | // return [NSString stringWithFormat:@"%@.jpg", self.identifier]; 93 | // else if (self.blob.overlay) 94 | // return self.identifier; 95 | // else 96 | // return [NSString stringWithFormat:@"%@.mp4", self.identifier]; 97 | } 98 | 99 | @end -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/GeneratedMessageBuilder.m: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "GeneratedMessageBuilder.h" 19 | 20 | #import "GeneratedMessage.h" 21 | #import "Message.h" 22 | #import "MessageBuilder.h" 23 | #import "UnknownFieldSet.h" 24 | #import "UnknownFieldSetBuilder.h" 25 | 26 | 27 | @interface PBGeneratedMessage () 28 | @property (strong) PBUnknownFieldSet* unknownFields; 29 | @end 30 | 31 | 32 | @implementation PBGeneratedMessageBuilder 33 | 34 | /** 35 | * Get the message being built. We don't just pass this to the 36 | * constructor because it becomes null when build() is called. 37 | */ 38 | - (PBGeneratedMessage*) internalGetResult { 39 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 40 | } 41 | 42 | 43 | - (void) checkInitialized { 44 | PBGeneratedMessage* result = self.internalGetResult; 45 | if (result != nil && !result.isInitialized) { 46 | @throw [NSException exceptionWithName:@"UninitializedMessage" reason:@"" userInfo:nil]; 47 | } 48 | } 49 | 50 | 51 | - (PBUnknownFieldSet*) unknownFields { 52 | return self.internalGetResult.unknownFields; 53 | } 54 | 55 | 56 | - (id) setUnknownFields:(PBUnknownFieldSet*) unknownFields { 57 | self.internalGetResult.unknownFields = unknownFields; 58 | return self; 59 | } 60 | 61 | 62 | - (id) mergeUnknownFields:(PBUnknownFieldSet*) unknownFields { 63 | PBGeneratedMessage* result = self.internalGetResult; 64 | result.unknownFields = 65 | [[[PBUnknownFieldSet builderWithUnknownFields:result.unknownFields] 66 | mergeUnknownFields:unknownFields] build]; 67 | return self; 68 | } 69 | 70 | 71 | - (BOOL) isInitialized { 72 | return self.internalGetResult.isInitialized; 73 | } 74 | 75 | 76 | /** 77 | * Called by subclasses to parse an unknown field. 78 | * @return {@code YES} unless the tag is an end-group tag. 79 | */ 80 | - (BOOL) parseUnknownField:(PBCodedInputStream*) input 81 | unknownFields:(PBUnknownFieldSetBuilder*) unknownFields 82 | extensionRegistry:(PBExtensionRegistry*) extensionRegistry 83 | tag:(SInt32) tag { 84 | return [unknownFields mergeFieldFrom:tag input:input]; 85 | } 86 | 87 | 88 | - (void) checkInitializedParsed { 89 | PBGeneratedMessage* result = self.internalGetResult; 90 | if (result != nil && !result.isInitialized) { 91 | @throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"" userInfo:nil]; 92 | } 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /Pod/Classes/Networking/SKClient+Snaps.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKClient+Snaps.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/26/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SKClient.h" 11 | #import "SKSnap.h" 12 | 13 | @class SKSnapOptions, CLLocation; 14 | 15 | 16 | @interface SKClient (Snaps) 17 | 18 | /** Sends a snap with the given options. 19 | @param blob The \c SKBlob object containing the image or video data to send. Can be created with any \c NSData object. 20 | @param options The options for the snap to be sent. 21 | @param completion Takes an error, if any, and an \c SKSnapResponse object. */ 22 | - (void)sendSnap:(SKBlob *)blob options:(SKSnapOptions *)options completion:(ResponseBlock)completion; 23 | /** Sends a snap to everyone in \c recipients with text \c text for \c duration seconds. 24 | @param blob The \c SKBlob object containing the image or video data to send. Can be created with any \c NSData object. 25 | @param recipients An array of username strings. 26 | @param text The text to label the snap with. This text is not superimposed upon the image; you must do that yourself. 27 | @param duration The legnth of the snap. It must be greater than \c 0 or an exception will be raised. 28 | @param completion Takes an error, if any, and an \c SKSnapResponse object. */ 29 | - (void)sendSnap:(SKBlob *)blob to:(NSArray *)recipients text:(NSString *)text timer:(NSTimeInterval)duration completion:(ResponseBlock)completion; 30 | 31 | /** Marks a snap as opened for \c secondsViewed seconds at the current time. 32 | @param secondsViewed The number of seconds the snap was viewed for. 33 | @param replayed Whether the snap was also replayed. 34 | @param completion Takes an error, if any. */ 35 | - (void)markSnapViewed:(SKSnap *)snap for:(CGFloat)secondsViewed replay:(BOOL)replayed completion:(ErrorBlock)completion; 36 | /** Marks a set of snaps as opened for the specified length at the given times. 37 | @param snaps An array of \c SKSnap objects. 38 | @param times An array of \c NSDate objects. 39 | @param replayed An array of NSNumber booleans indicating whether the corresponding snap was replayed. 40 | @param secondsViewed An array of \c NSNumber objects. Try to use floating point nubmers. */ 41 | - (void)markSnapsViewed:(NSArray *)snaps atTimes:(NSArray *)times for:(NSArray *)secondsViewed replayed:(NSArray *)replayed completion:(ErrorBlock)completion; 42 | /** Marks a snap as screenshotted and viewed for \c secondsViewed seconds. 43 | @param secondsViewed The number of seconds the corresponding snap was viewed for. 44 | @param replayed An array of NSNumber booleans indicating whether the corresponding snap was replayed. 45 | @param completion Takes an error, if any. */ 46 | - (void)markSnapScreenshot:(SKSnap *)snap for:(NSUInteger)secondsViewed completion:(ErrorBlock)completion; 47 | 48 | /** Loads a snap. 49 | @param completion Takes an error, if any, and an \c SKBlob object. */ 50 | - (void)loadSnap:(SKSnap *)snap completion:(ResponseBlock)completion; 51 | 52 | /** Loads filters for a location. 53 | @param completion Takes an error, if any, and an \c SKLocation object. */ 54 | - (void)loadFiltersForLocation:(CLLocation *)location completion:(ResponseBlock)completion; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Pod/Classes/Networking/SKClient+Device.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKClient+Device.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/14/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKClient+Device.h" 10 | #import "SKUser.h" 11 | #import "SKRequest.h" 12 | 13 | #import "NSString+SnapchatKit.h" 14 | #import "NSArray+SnapchatKit.h" 15 | #import "NSDictionary+SnapchatKit.h" 16 | 17 | #define kUnimplemented @"Unimplemented" 18 | 19 | @implementation SKClient (Device) 20 | 21 | - (void)sendDidOpenAppEvent:(ErrorBlock)completion { 22 | [self updateSession:^(NSError *error) { 23 | if (!error) { 24 | NSString *uuid = SKUniqueIdentifier(); 25 | NSInteger friendCount = -1; 26 | 27 | for (SKUser *friend in self.currentSession.friends) 28 | if (friend.friendStatus == SKFriendStatusMutual) 29 | friendCount++; 30 | 31 | NSString *timestamp = [NSString timestamp]; 32 | NSString *batchID = [NSString stringWithFormat:@"%@-%@%@", uuid, [SKConsts.userAgent stringByReplacingMatchesForRegex:@"[\\W]+" withString:@""], timestamp]; 33 | NSDictionary *eventDict = @{@"common_params": @{@"user_id":self.username.MD5Hash, 34 | @"city": kUnimplemented, 35 | @"sc_user_agent": SKConsts.userAgent, 36 | @"session_id":@"00000000-0000-0000-0000-000000000000", 37 | @"region": kUnimplemented, 38 | @"latlon": kUnimplemented, 39 | @"friend_count": @(friendCount), 40 | @"country": kUnimplemented}.JSONString, 41 | @"events": @[@{@"event_name": @"APP_OPEN", 42 | @"event_timestamp": timestamp, 43 | @"event_params": @{@"open_state": @"NORMAL", @"intent_action": @"NULL"}.JSONString}.JSONString].JSONString, 44 | @"batch_id": batchID}; 45 | 46 | [SKRequest sendEvents:eventDict callback:^(NSData *data, NSURLResponse *response, NSError *error) { 47 | if (completion) { 48 | if ([(NSHTTPURLResponse *)response statusCode] == 200) { 49 | completion(nil); 50 | } else { 51 | [self handleError:error data:data response:response completion:^(id object, NSError *error) { 52 | completion(error); 53 | }]; 54 | } 55 | } 56 | }]; 57 | 58 | } else { 59 | completion(error); 60 | } 61 | }]; 62 | } 63 | 64 | - (void)sendDidCloseAppEvent:(ErrorBlock)completion { 65 | NSArray *events = @[@{@"eventName": @"CLOSE", 66 | @"params": @{}, 67 | @"ts": [NSString timestamp]}]; 68 | [self sendEvents:events data:nil completion:completion]; 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/AbstractMessage.m: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "AbstractMessage.h" 19 | 20 | #import "CodedOutputStream.h" 21 | 22 | @implementation PBAbstractMessage 23 | 24 | - (instancetype) init { 25 | if ((self = [super init])) { 26 | } 27 | 28 | return self; 29 | } 30 | 31 | 32 | - (NSData*) data { 33 | NSMutableData* data = [NSMutableData dataWithLength:self.serializedSize]; 34 | PBCodedOutputStream* stream = [PBCodedOutputStream streamWithData:data]; 35 | [self writeToCodedOutputStream:stream]; 36 | return data; 37 | } 38 | 39 | 40 | - (BOOL) isInitialized { 41 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 42 | } 43 | 44 | 45 | - (SInt32) serializedSize { 46 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 47 | } 48 | 49 | 50 | - (void) writeToCodedOutputStream:(PBCodedOutputStream*) output { 51 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 52 | } 53 | 54 | 55 | - (void) writeToOutputStream:(NSOutputStream*) output { 56 | PBCodedOutputStream* codedOutput = [PBCodedOutputStream streamWithOutputStream:output]; 57 | [self writeToCodedOutputStream:codedOutput]; 58 | [codedOutput flush]; 59 | } 60 | 61 | 62 | - (instancetype) defaultInstance { 63 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 64 | } 65 | 66 | 67 | - (PBUnknownFieldSet*) unknownFields { 68 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 69 | } 70 | 71 | 72 | - (id) builder { 73 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 74 | } 75 | 76 | 77 | - (id) toBuilder { 78 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 79 | } 80 | 81 | 82 | - (void) writeDescriptionTo:(NSMutableString*) output 83 | withIndent:(NSString*) indent { 84 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 85 | } 86 | 87 | 88 | - (NSString*) description { 89 | NSMutableString* output = [NSMutableString string]; 90 | [self writeDescriptionTo:output withIndent:@""]; 91 | return output; 92 | } 93 | 94 | - (void) storeInDictionary: (NSMutableDictionary *) dic { 95 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 96 | } 97 | 98 | - (NSDictionary *) dictionaryRepresentation { 99 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil]; 100 | } 101 | 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /Pod/Classes/Categories/NSDictionary+SnapchatKit.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+SnapchatKit.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/22/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+SnapchatKit.h" 10 | #import "NSString+SnapchatKit.h" 11 | #import "NSData+SnapchatKit.h" 12 | #import 13 | #import 14 | 15 | 16 | @implementation NSDictionary (JSON) 17 | 18 | - (NSString *)JSONString { 19 | NSData *data = [NSJSONSerialization dataWithJSONObject:self options:0 error:nil]; 20 | return data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : @"{}"; 21 | } 22 | 23 | - (NSString *)JWTStringWithSecret:(NSString *)key { 24 | NSString *header = @"{\"typ\":\"JWT\",\"alg\":\"HS256\"}"; 25 | NSString *payload = [self.JSONString stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]; 26 | 27 | NSString *data = [@"." join:@[header.base64URLEncoded, payload.base64URLEncoded]]; 28 | 29 | unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; 30 | CCHmac(kCCHmacAlgSHA256, key.UTF8String, strlen(key.UTF8String), data.UTF8String, strlen(data.UTF8String), cHMAC); 31 | NSData *signature = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)]; 32 | 33 | return [@"." join:@[data, signature.base64URLEncodedString]]; 34 | } 35 | 36 | @end 37 | 38 | 39 | @implementation NSDictionary (Util) 40 | 41 | - (NSArray *)split:(NSUInteger)entryLimit { 42 | NSParameterAssert(entryLimit > 0); 43 | if (self.allKeys.count <= entryLimit) 44 | return @[self]; 45 | 46 | NSMutableArray *dicts = [NSMutableArray array]; 47 | __block NSMutableDictionary *tmp = [NSMutableDictionary dictionary]; 48 | [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 49 | tmp[key] = obj; 50 | if (tmp.allKeys.count % entryLimit == 0) { 51 | [dicts addObject:tmp]; 52 | tmp = [NSMutableDictionary dictionary]; 53 | } 54 | }]; 55 | 56 | return dicts; 57 | } 58 | 59 | - (NSDictionary *)dictionaryByReplacingValuesForKeys:(NSDictionary *)dictionary { 60 | if (!dictionary || !dictionary.allKeys.count || !self) return self; 61 | 62 | NSMutableDictionary *m = self.mutableCopy; 63 | [m setValuesForKeysWithDictionary:dictionary]; 64 | return m.copy; 65 | } 66 | 67 | - (NSDictionary *)dictionaryByReplacingKeysWithNewKeys:(NSDictionary *)oldKeysToNewKeys { 68 | if (!oldKeysToNewKeys || !oldKeysToNewKeys.allKeys.count || !self) return self; 69 | 70 | NSMutableDictionary *m = self.mutableCopy; 71 | [oldKeysToNewKeys enumerateKeysAndObjectsUsingBlock:^(NSString *oldKey, NSString *newKey, BOOL *stop) { 72 | id val = m[oldKey]; 73 | m[oldKey] = nil; 74 | m[newKey] = val; 75 | }]; 76 | 77 | return m; 78 | } 79 | 80 | - (NSArray *)allKeyPaths { 81 | NSMutableArray *keyPaths = [NSMutableArray array]; 82 | 83 | [self enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { 84 | [keyPaths addObject:key]; 85 | 86 | if ([obj isKindOfClass:[NSDictionary class]]) { 87 | for (NSString *kp in [obj allKeyPaths]) 88 | [keyPaths addObject:[NSString stringWithFormat:@"%@.%@", key, kp]]; 89 | } 90 | }]; 91 | 92 | return keyPaths.copy; 93 | } 94 | 95 | @end -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ExtensionRegistry.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | /** 19 | * A table of known extensions, searchable by name or field number. When 20 | * parsing a protocol message that might have extensions, you must provide 21 | * an {@code ExtensionRegistry} in which you have registered any extensions 22 | * that you want to be able to parse. Otherwise, those extensions will just 23 | * be treated like unknown fields. 24 | * 25 | *

For example, if you had the {@code .proto} file: 26 | * 27 | *

28 |  * option java_class = "MyProto";
29 |  *
30 |  * message Foo {
31 |  *   extensions 1000 to max;
32 |  * }
33 |  *
34 |  * extend Foo {
35 |  *   optional int32 bar;
36 |  * }
37 |  * 
38 | * 39 | * Then you might write code like: 40 | * 41 | *
42 |  * ExtensionRegistry registry = ExtensionRegistry.newInstance();
43 |  * registry.add(MyProto.bar);
44 |  * MyProto.Foo message = MyProto.Foo.parseFrom(input, registry);
45 |  * 
46 | * 47 | *

Background: 48 | * 49 | *

You might wonder why this is necessary. Two alternatives might come to 50 | * mind. First, you might imagine a system where generated extensions are 51 | * automatically registered when their containing classes are loaded. This 52 | * is a popular technique, but is bad design; among other things, it creates a 53 | * situation where behavior can change depending on what classes happen to be 54 | * loaded. It also introduces a security vulnerability, because an 55 | * unprivileged class could cause its code to be called unexpectedly from a 56 | * privileged class by registering itself as an extension of the right type. 57 | * 58 | *

Another option you might consider is lazy parsing: do not parse an 59 | * extension until it is first requested, at which point the caller must 60 | * provide a type to use. This introduces a different set of problems. First, 61 | * it would require a mutex lock any time an extension was accessed, which 62 | * would be slow. Second, corrupt data would not be detected until first 63 | * access, at which point it would be much harder to deal with it. Third, it 64 | * could violate the expectation that message objects are immutable, since the 65 | * type provided could be any arbitrary message class. An unpriviledged user 66 | * could take advantage of this to inject a mutable object into a message 67 | * belonging to priviledged code and create mischief. 68 | * 69 | * @author Cyrus Najmabadi 70 | */ 71 | 72 | #import "ExtensionField.h" 73 | 74 | @interface PBExtensionRegistry : NSObject { 75 | @protected 76 | NSDictionary* classMap; 77 | } 78 | 79 | + (PBExtensionRegistry*) emptyRegistry; 80 | - (id) getExtension:(Class) clazz fieldNumber:(SInt32) fieldNumber; 81 | 82 | /* @protected */ 83 | - (instancetype) initWithClassMap:(NSDictionary*) classMap; 84 | - (id) keyForClass:(Class) clazz; 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStory.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKStory.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SKThing.h" 11 | #import "SKBlob.h" 12 | 13 | @interface SKStory : SKThing 14 | 15 | /** The username of whoever posted this story. */ 16 | @property (nonatomic, readonly) NSString *author; 17 | 18 | /** The length of the snap in seconds. */ 19 | @property (nonatomic, readonly) NSUInteger duration; 20 | 21 | /** Whether the story has been viewed. */ 22 | @property (nonatomic, readonly) BOOL viewed; 23 | /** Whether the story is a "live" or "shared" story. */ 24 | @property (nonatomic, readonly) BOOL shared; 25 | /** Whether the story is zipped (video stories with an overlay will be zipped). */ 26 | @property (nonatomic, readonly) BOOL zipped; 27 | /** Whether the story contains explicit content. */ 28 | @property (nonatomic, readonly) BOOL matureContent; 29 | /** Not sure. */ 30 | @property (nonatomic, readonly) BOOL needsAuth; 31 | 32 | /** The story's ID. Fun fact: this value is just username + timestamp string. */ 33 | @property (nonatomic, readonly) NSString *identifier; 34 | /** The text of the story. */ 35 | @property (nonatomic, readonly) NSString *text; 36 | /** Unknown */ 37 | @property (nonatomic, readonly) NSArray *unlockables; 38 | /** Unknown */ 39 | @property (nonatomic, readonly) NSString *clientIdentifier; 40 | /** Unknown */ 41 | @property (nonatomic, readonly) NSString *submissionIdentifier; 42 | 43 | /** Unknown */ 44 | @property (nonatomic, readonly) NSString *storyFilterIdentifier; 45 | /** Unknown */ 46 | @property (nonatomic, readonly) BOOL adCanFollow; 47 | 48 | /** The story's media ID. */ 49 | @property (nonatomic, readonly) NSString *mediaIdentifier; 50 | /** The IV used to decrypt the media. */ 51 | @property (nonatomic, readonly) NSString *mediaIV; 52 | /** The key used to decrypt the media. */ 53 | @property (nonatomic, readonly) NSString *mediaKey; 54 | @property (nonatomic, readonly) SKMediaKind mediaKind; 55 | /** The URL of the media. */ 56 | @property (nonatomic, readonly) NSURL *mediaURL; 57 | 58 | /** The IV used to decrypt the thumbnail. */ 59 | @property (nonatomic, readonly) NSString *thumbIV; 60 | /** The URL of the thumbnail. */ 61 | @property (nonatomic, readonly) NSURL *thumbURL; 62 | 63 | /** The number of seconds left before the story expires. */ 64 | @property (nonatomic, readonly) NSUInteger timeLeft; 65 | /** The date the story was created. */ 66 | @property (nonatomic, readonly) NSDate *created; 67 | 68 | /** \c nil until you call \c load: */ 69 | @property (nonatomic, readonly) SKBlob *blob; 70 | /** \c nil until you call \c loadThumbnail: */ 71 | @property (nonatomic, readonly) SKBlob *thumbnailBlob; 72 | 73 | @end 74 | 75 | @interface SKStory (SKClient) 76 | /** Loads the blob for the story. If successful, the \c blob property of the original \c SKStory object will contain the story's blob data. 77 | @param completion Takes an error, if any. */ 78 | - (void)load:(ErrorBlock)completion; 79 | /** Loads the blob for the story thumbnail. If successful, the \c thumbnailBlob property of the original \c SKStory object will contain the story's thumbnail blob data. 80 | @param completion Takes an error, if any. */ 81 | - (void)loadThumbnail:(ErrorBlock)completion; 82 | /** @return If \c blob is \c nil, returns nil. For images: \c {identifier}.jpg, for videos: \c {identifier}.mp4, and for videos with an overlay just {identifier} */ 83 | @property (nonatomic, readonly) NSString *suggestedFilename; 84 | 85 | @end -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/ExtendableMessage.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "GeneratedMessage.h" 19 | 20 | #import "ExtensionField.h" 21 | 22 | /** 23 | * Generated message classes for message types that contain extension ranges 24 | * subclass this. 25 | * 26 | *

This class implements type-safe accessors for extensions. They 27 | * implement all the same operations that you can do with normal fields -- 28 | * e.g. "has", "get", and "getCount" -- but for extensions. The extensions 29 | * are identified using instances of the class {@link GeneratedExtension}; 30 | * the protocol compiler generates a static instance of this class for every 31 | * extension in its input. Through the magic of generics, all is made 32 | * type-safe. 33 | * 34 | *

For example, imagine you have the {@code .proto} file: 35 | * 36 | *

37 |  * option java_class = "MyProto";
38 |  *
39 |  * message Foo {
40 |  *   extensions 1000 to max;
41 |  * }
42 |  *
43 |  * extend Foo {
44 |  *   optional int32 bar;
45 |  * }
46 |  * 
47 | * 48 | *

Then you might write code like: 49 | * 50 | *

51 |  * MyProto.Foo foo = getFoo();
52 |  * int i = foo.getExtension(MyProto.bar);
53 |  * 
54 | * 55 | *

See also {@link ExtendableBuilder}. 56 | */ 57 | @interface PBExtendableMessage : PBGeneratedMessage { 58 | @private 59 | NSMutableDictionary* extensionMap; 60 | NSMutableDictionary* extensionRegistry; 61 | } 62 | 63 | @property (strong) NSMutableDictionary* extensionMap; 64 | @property (strong) NSMutableDictionary* extensionRegistry; 65 | 66 | - (BOOL) hasExtension:(id) extension; 67 | - (id) getExtension:(id) extension; 68 | 69 | //@protected 70 | - (BOOL) extensionsAreInitialized; 71 | - (SInt32) extensionsSerializedSize; 72 | - (void) writeExtensionsToCodedOutputStream:(PBCodedOutputStream*) output 73 | from:(SInt32) startInclusive 74 | to:(SInt32) endExclusive; 75 | - (void) writeExtensionDescriptionToMutableString:(NSMutableString*) output 76 | from:(SInt32) startInclusive 77 | to:(SInt32) endExclusive 78 | withIndent:(NSString*) indent; 79 | - (void) addExtensionDictionaryEntriesToMutableDictionary:(NSMutableDictionary*) output 80 | from:(int32_t) startInclusive 81 | to:(int32_t) endExclusive; 82 | - (BOOL) isEqualExtensionsInOther:(PBExtendableMessage*)otherMessage 83 | from:(SInt32) startInclusive 84 | to:(SInt32) endExclusive; 85 | - (NSUInteger) hashExtensionsFrom:(SInt32) startInclusive 86 | to:(SInt32) endExclusive; 87 | 88 | 89 | 90 | /* @internal */ 91 | - (void) ensureExtensionIsRegistered:(id) extension; 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKBlob.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKBlob.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/13/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SnapchatKit-Constants.h" 11 | 12 | @class SKStory; 13 | 14 | extern NSData * SKThumbnailFromGCImage(CGImageRef image); 15 | 16 | /** A wrapper for the various kinds of data used throughout the API. */ 17 | @interface SKBlob : NSObject 18 | 19 | /** Initializes a blob with the snap found at \c path. 20 | @discussion \c path can be a path to a folder (containing a video and overlay) or a single snap. 21 | @param path The path to a single snap or a folder containing a video and overlay. 22 | @return An initialized \c SKBlob object, or \c nil if there was a problem initializing it. If \c path is a directory, this method will look for the contents of unzipped media specifically. */ 23 | + (instancetype)blobWithContentsOfPath:(NSString *)path; 24 | /** Initializes a blob with anonymous data. */ 25 | + (instancetype)blobWithData:(NSData *)data; 26 | /** Initializes a blob with story data and passes it to the completion block. 27 | @discussion This method is specifically for story blobs, because they \e used to be CBC encrypted and possibly zipped if it's a video. Yes: stories are no longer encrypted. Get it together, Snapchat... 28 | @param blobData Pretty self explanatory. 29 | @param story The story you wish to retrieve. 30 | @param Whether the data is for a thumbnail or not. 31 | @param completion Takes an error, if any, and an \c SKBlob object. */ 32 | + (void)blobWithStoryData:(NSData *)blobData forStory:(SKStory *)story isThumb:(BOOL)thumb completion:(ResponseBlock)completion; 33 | 34 | /** Used to unarchive blobs initialized with anonymous data. 35 | @param completion Takes an error, if any, and new \c SKBlob object. Returns immediately if the blob was not compressed. */ 36 | - (void)decompress:(ResponseBlock)completion; 37 | 38 | /** Conveniently writes all data associated with the \c SKBlob object to the disk. 39 | @discussion If the blob has an overlay, this method will write the data and overlay to a folder as \c filename/filename.[jpg|mp4] and \c filename/filename.jpg. 40 | If not, only \c data is written to the specified file. 41 | @param path The \e directory to which to write the receiver's bytes. Pass the desired filename to \e filename. See \c -[NSData writeToFile:atomically:] for more information. 42 | @param filename The name to serialize the blob under. 43 | @param atomically See \c -[NSData writeToFile:atomically:] 44 | @return An array of strings paths to the written files. Overlay is always the second object if applicable. */ 45 | - (NSArray *)writeToPath:(NSString *)directoryPath filename:(NSString *)filename atomically:(BOOL)atomically; 46 | 47 | /** The data for the image or video. */ 48 | @property (nonatomic, readonly) NSData *data; 49 | /** The overlay for the video. \c nil if not applicable. */ 50 | @property (nonatomic, readonly) NSData *overlay; 51 | /** Lazily initialized. The compressed data for the snap should it be uploaded. nil if not need be compressed. */ 52 | @property (nonatomic, readonly) NSData *zipData; 53 | /** Lazily initialized. 54 | @discussion The thumbnail for the video to be uploaded. nil if not applicable. 55 | @note You may assign your own if you wish, and it will be used instead of the default one. */ 56 | @property (nonatomic ) NSData *videoThumbnail; 57 | /** \c YES if the data is for a JPEG, \c NO if it's something other than a JPEG or PNG. */ 58 | @property (nonatomic, readonly) BOOL isImage; 59 | /** \c YES if the data is for a MPEG4 video, \c NO if it's something else. */ 60 | @property (nonatomic, readonly) BOOL isVideo; 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Pod/Classes/Networking/SKClient+Stories.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKClient+Stories.h 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 6/13/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SKClient.h" 11 | #import "SKBlob.h" 12 | 13 | @class SKStory, SKUserStory, SKStoryCollection, SKStoryOptions; 14 | 15 | 16 | @interface SKClient (Stories) 17 | 18 | /** Posts a story with the given options. 19 | @param blob The \c SKBlob object containing the image or video data to send. Can be created with any \c NSData object. 20 | @param options The options for the story to post. 21 | @param completion Takes an error, if any. */ 22 | - (void)postStory:(SKBlob *)blob options:(SKStoryOptions *)options completion:(ErrorBlock)completion; 23 | /** Posts a story with the given options. 24 | @param blob The \c SKBlob object containing the image or video data to send. Can be created with any \c NSData object. 25 | @param duration The length of the story. This value is ignored for video snaps. 26 | @param completion Takes an error, if any. 27 | @note Assumes camera not front facing. */ 28 | - (void)postStory:(SKBlob *)blob for:(NSTimeInterval)duration completion:(ErrorBlock)completion; 29 | 30 | /** Downloads media for a story. 31 | @param story The story to download. 32 | @param completion Takes an error, if any, and an \c SKBlob object. */ 33 | - (void)loadStoryBlob:(SKStory *)story completion:(ResponseBlock)completion; 34 | /** Downloads the thumbnail for a story. 35 | @param story The story whose thumbnail you wish to download. 36 | @param completion Takes an error, if any, and an \c SKBlob object. */ 37 | - (void)loadStoryThumbnailBlob:(SKStory *)story completion:(ResponseBlock)completion; 38 | 39 | /** Batch loads media for a set of stories. 40 | @param stories An array of \c SKStory objects whose media you wish to download. 41 | @param completion Takes an error, if any, an array of \c SKStory objects with initialized \c blob properties, and an array of \c SKStory objects that could not be retrieved, if any. */ 42 | - (void)loadStories:(NSArray *)stories completion:(CollectionResponseBlock)completion; 43 | 44 | /** Deletes a story of yours. 45 | @param completion Takes an error, if any. */ 46 | - (void)deleteStory:(SKUserStory *)story completion:(ErrorBlock)completion; 47 | 48 | /** Marks a set of stories as opened. 49 | @param stories An array of \c SKStoryUpdater objects. 50 | @param completion Takes an error, if any. */ 51 | - (void)markStoriesViewed:(NSArray *)stories completion:(ErrorBlock)completion; 52 | /** Marks a single story opened. 53 | @discussion To batch mark stories viewed, use \c -markStoriesViewed:completion:. 54 | @param story The story to mark as opened. 55 | @param sscount The number of times the story was screenshotted. 56 | @param completion Takes an error, if any. */ 57 | - (void)markStoryViewed:(SKStory *)story screenshotCount:(NSUInteger)sscount completion:(ErrorBlock)completion; 58 | 59 | /** Hides a shared story from the story feed. 60 | @param completion Takes an error, if any. */ 61 | - (void)hideSharedStory:(SKStoryCollection *)story completion:(ErrorBlock)completion; 62 | 63 | /** I forget what this is for. Does nothing if the story is not a shared story. 64 | @param sharedStory A shared story. 65 | @param completion Takes an error, if any. */ 66 | - (void)provideSharedDescription:(SKStory *)sharedStory completion:(ErrorBlock)completion; 67 | 68 | /** Retrieves the description for a shared story. 69 | @param sharedStory A shared story. 70 | @param completion Takes an error, if any, and an \c SKSharedStoryDescription object. */ 71 | - (void)getSharedDescriptionForStory:(SKUser *)sharedStory completion:(ResponseBlock)completion; 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Pod/Classes/Model/SKStory.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKStory.m 3 | // SnapchatKit 4 | // 5 | // Created by Tanner Bennett on 5/18/15. 6 | // Copyright (c) 2015 Tanner Bennett. All rights reserved. 7 | // 8 | 9 | #import "SKStory.h" 10 | #import "SKClient+Stories.h" 11 | 12 | @implementation SKStory 13 | 14 | - (NSString *)description { 15 | return [NSString stringWithFormat:@"<%@ shared=%d, zipped=%d, auth=%d, viewed=%d, duration=%lu, text=%@, time left=%lu>", 16 | NSStringFromClass(self.class), self.shared, self.zipped, self.needsAuth, self.viewed, (unsigned long)self.duration, self.text, (unsigned long)self.timeLeft]; 17 | } 18 | 19 | #pragma mark - Mantle 20 | 21 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 22 | return @{@"author": @"story.username", 23 | @"viewed": @"viewed", 24 | @"shared": @"story.is_shared", 25 | @"zipped": @"story.zipped", 26 | @"matureContent": @"story.mature_content", 27 | @"needsAuth": @"story.needs_auth", 28 | @"duration": @"story.time", 29 | @"identifier": @"story.id", 30 | @"text": @"story.caption_text_display", 31 | @"clientIdentifier": @"story.client_id", 32 | @"storyFilterIdentifier": @"story.story_filter_id", 33 | @"adCanFollow": @"story.ad_can_follow", 34 | @"mediaIdentifier": @"story.media_id", 35 | @"mediaIV": @"story.media_iv", 36 | @"mediaKey": @"story.media_key", 37 | @"mediaKind": @"story.media_type", 38 | @"mediaURL": @"story.media_url", 39 | @"thumbIV": @"story.thumbnail_iv", 40 | @"thumbURL": @"story.thumbnail_url", 41 | @"timeLeft": @"story.time_left", 42 | @"created": @"story.timestamp", 43 | @"submissionIdentifier": @"story.submission_id", 44 | @"unlockables": @"story.unlockables"}; 45 | } 46 | 47 | MTLTransformPropertyURL(mediaURL) 48 | MTLTransformPropertyURL(thumbURL) 49 | MTLTransformPropertyDate(created) 50 | 51 | #pragma mark - Equality 52 | 53 | - (BOOL)isEqual:(id)object { 54 | if ([object isKindOfClass:[SKStory class]]) 55 | return [self isEqualToStory:object]; 56 | 57 | return [super isEqual:object]; 58 | } 59 | 60 | - (BOOL)isEqualToStory:(SKStory *)story { 61 | return [story.identifier isEqualToString:self.identifier]; 62 | } 63 | 64 | - (NSUInteger)hash { 65 | return self.identifier.hash; 66 | } 67 | 68 | @end 69 | 70 | @implementation SKStory (SKClient) 71 | 72 | - (void)load:(ErrorBlock)completion { 73 | NSParameterAssert(completion); 74 | [[SKClient sharedClient] loadStoryBlob:self completion:^(SKBlob *blob, NSError *error) { 75 | if (!error) { 76 | _blob = blob; 77 | completion(nil); 78 | } else { 79 | completion(error); 80 | } 81 | }]; 82 | } 83 | 84 | - (void)loadThumbnail:(ErrorBlock)completion { 85 | NSParameterAssert(completion); 86 | [[SKClient sharedClient] loadStoryThumbnailBlob:self completion:^(SKBlob *blob, NSError *error) { 87 | if (!error) { 88 | _thumbnailBlob = blob; 89 | completion(nil); 90 | } else { 91 | completion(error); 92 | } 93 | }]; 94 | } 95 | 96 | - (NSString *)suggestedFilename { 97 | if (!self.blob) 98 | return nil; 99 | if (self.blob.isImage) 100 | return [NSString stringWithFormat:@"%@.jpg", self.identifier]; 101 | else if (self.blob.overlay) 102 | return self.identifier; 103 | else 104 | return [NSString stringWithFormat:@"%@.mp4", self.identifier]; 105 | } 106 | 107 | @end -------------------------------------------------------------------------------- /Pod/Dependencies/SSZipArchive.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSZipArchive.h 3 | // SSZipArchive 4 | // 5 | // Created by Sam Soffes on 7/21/10. 6 | // Copyright (c) Sam Soffes 2010-2015. All rights reserved. 7 | // 8 | 9 | #ifndef _SSZIPARCHIVE_H 10 | #define _SSZIPARCHIVE_H 11 | 12 | #import 13 | #include "unzip.h" 14 | 15 | @protocol SSZipArchiveDelegate; 16 | 17 | @interface SSZipArchive : NSObject 18 | 19 | // Unzip 20 | + (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination completion:(void (^)(NSString *path, BOOL succeeded, NSError *error))completion; 21 | + (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination; 22 | + (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id)delegate; 23 | 24 | + (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error; 25 | + (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error delegate:(id)delegate; 26 | 27 | + (BOOL)unzipFileAtPath:(NSString *)path 28 | toDestination:(NSString *)destination 29 | progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler 30 | completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler; 31 | 32 | + (BOOL)unzipFileAtPath:(NSString *)path 33 | toDestination:(NSString *)destination 34 | overwrite:(BOOL)overwrite 35 | password:(NSString *)password 36 | progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler 37 | completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler; 38 | 39 | // Zip 40 | + (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)filenames; 41 | + (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath; 42 | + (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory; 43 | 44 | - (id)initWithPath:(NSString *)path; 45 | - (BOOL)open; 46 | - (BOOL)writeFile:(NSString *)path; 47 | - (BOOL)writeFileAtPath:(NSString *)path withFileName:(NSString *)fileName; 48 | - (BOOL)writeData:(NSData *)data filename:(NSString *)filename; 49 | - (BOOL)close; 50 | 51 | @end 52 | 53 | @protocol SSZipArchiveDelegate 54 | 55 | @optional 56 | 57 | - (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo; 58 | - (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath; 59 | 60 | - (BOOL)zipArchiveShouldUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo; 61 | - (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo; 62 | - (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo; 63 | - (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath unzippedFilePath:(NSString *)unzippedFilePath; 64 | 65 | - (void)zipArchiveProgressEvent:(unsigned long long)loaded total:(unsigned long long)total; 66 | - (void)zipArchiveDidUnzipArchiveFile:(NSString *)zipFile entryPath:(NSString *)entryPath destPath:(NSString *)destPath; 67 | 68 | @end 69 | 70 | #endif /* _SSZIPARCHIVE_H */ 71 | -------------------------------------------------------------------------------- /Pod/Dependencies/protobuf/MutableField.m: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Objective C 2 | // 3 | // Copyright 2010 Booyah Inc. 4 | // Copyright 2008 Cyrus Najmabadi 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #import "MutableField.h" 19 | 20 | #import "Field.h" 21 | #import "PBArray.h" 22 | 23 | @implementation PBMutableField 24 | 25 | 26 | + (PBMutableField *)field { 27 | return [[PBMutableField alloc] init]; 28 | } 29 | 30 | - (PBMutableField *)clear { 31 | 32 | _varintArray = nil; 33 | _fixed32Array = nil; 34 | _fixed64Array = nil; 35 | _lengthDelimitedArray = nil; 36 | _groupArray = nil; 37 | 38 | return self; 39 | } 40 | 41 | - (PBMutableField *)mergeFromField:(PBField *)other { 42 | if (other.varintArray.count > 0) { 43 | if (_varintArray == nil) { 44 | _varintArray = [other.varintArray copy]; 45 | } else { 46 | [_varintArray appendArray:other.varintArray]; 47 | } 48 | } 49 | 50 | if (other.fixed32Array.count > 0) { 51 | if (_fixed32Array == nil) { 52 | _fixed32Array = [other.fixed32Array copy]; 53 | } else { 54 | [_fixed32Array appendArray:other.fixed32Array]; 55 | } 56 | } 57 | 58 | if (other.fixed64Array.count > 0) { 59 | if (_fixed64Array == nil) { 60 | _fixed64Array = [other.fixed64Array copy]; 61 | } else { 62 | [_fixed64Array appendArray:other.fixed64Array]; 63 | } 64 | } 65 | 66 | if (other.lengthDelimitedArray.count > 0) { 67 | if (_lengthDelimitedArray == nil) { 68 | _lengthDelimitedArray = [other.lengthDelimitedArray copy]; 69 | } else { 70 | [_lengthDelimitedArray addObjectsFromArray:other.lengthDelimitedArray]; 71 | } 72 | } 73 | 74 | if (other.groupArray.count > 0) { 75 | if (_groupArray == nil) { 76 | _groupArray = [other.groupArray copy]; 77 | } else { 78 | [_groupArray addObjectsFromArray:other.groupArray]; 79 | } 80 | } 81 | 82 | return self; 83 | } 84 | 85 | - (PBMutableField *)addVarint:(SInt64)value { 86 | if (_varintArray == nil) { 87 | _varintArray = [[PBAppendableArray alloc] initWithValueType:PBArrayValueTypeInt64]; 88 | } 89 | [_varintArray addInt64:value]; 90 | 91 | return self; 92 | } 93 | 94 | - (PBMutableField *)addFixed32:(SInt32)value { 95 | if (_fixed32Array == nil) { 96 | _fixed32Array = [[PBAppendableArray alloc] initWithValueType:PBArrayValueTypeInt32]; 97 | } 98 | [_fixed32Array addInt32:value]; 99 | 100 | return self; 101 | } 102 | 103 | - (PBMutableField *)addFixed64:(SInt64)value { 104 | if (_fixed64Array == nil) { 105 | _fixed64Array = [[PBAppendableArray alloc] initWithValueType:PBArrayValueTypeInt64]; 106 | } 107 | [_fixed64Array addInt64:value]; 108 | 109 | return self; 110 | } 111 | 112 | - (PBMutableField *)addLengthDelimited:(NSData *)value { 113 | if (_lengthDelimitedArray == nil) { 114 | _lengthDelimitedArray = [[NSMutableArray alloc] init]; 115 | } 116 | [_lengthDelimitedArray addObject:value]; 117 | 118 | return self; 119 | } 120 | 121 | - (PBMutableField *)addGroup:(PBUnknownFieldSet *)value { 122 | if (_groupArray == nil) { 123 | _groupArray = [[NSMutableArray alloc] init]; 124 | } 125 | [_groupArray addObject:value]; 126 | 127 | return self; 128 | } 129 | 130 | @end --------------------------------------------------------------------------------