├── .gitignore ├── README.md └── iOS Wrapper ├── iZettle Wrapper Sample ├── iZettle Wrapper Sample │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── icon120.png │ │ │ ├── icon152.png │ │ │ ├── icon180.png │ │ │ ├── icon76.png │ │ │ └── Contents.json │ │ └── Wheel.imageset │ │ │ ├── wheel~ipad.png │ │ │ ├── wheel@2x~ipad.png │ │ │ ├── wheel~iphone.png │ │ │ ├── wheel@2x~iphone.png │ │ │ ├── wheel@3x~iphone.png │ │ │ └── Contents.json │ ├── ViewController.h │ ├── ConsoleViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── AmountWheel.h │ ├── AppDelegate.m │ ├── ConsoleViewController.m │ ├── Info.plist │ ├── AmountWheel.m │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ ├── Main~ipad.storyboard │ │ └── Main~iphone.storyboard │ └── ViewController.m └── iZettle Wrapper Sample.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ └── project.pbxproj ├── README.md └── iZettleURLScheme ├── iZettleURLScheme.h └── iZettleURLScheme.m /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | xcuserdata 3 | *.pbxuser 4 | *.perspectivev3 5 | *.mode1v3 6 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #URL Scheme is being deprecated 2 | 3 | The URL Scheme is in the process of being deprecated and integrators are encouraged to change to the SDK. The SDK can be downloaded from https://github.com/iZettle/sdk-ios. 4 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon120.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon152.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon180.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/AppIcon.appiconset/icon76.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel~ipad.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel@2x~ipad.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel~iphone.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel@2x~iphone.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel@3x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iZettle/URL-Scheme/HEAD/iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/wheel@3x~iphone.png -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface ViewController : UIViewController 11 | 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/ConsoleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ConsoleViewController.h 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface ConsoleViewController : UIViewController 11 | 12 | - (void)addToLog:(id)object; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface AppDelegate : UIResponder 11 | 12 | @property (strong, nonatomic) UIWindow *window; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "AppDelegate.h" 10 | 11 | int main(int argc, char * argv[]) { 12 | @autoreleasepool { 13 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/AmountWheel.h: -------------------------------------------------------------------------------- 1 | // 2 | // AmountWheel.h 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | typedef void (^AmountUpdateBlock)(NSDecimalNumber *amount); 11 | 12 | @interface AmountWheel : UIImageView 13 | 14 | @property (nonatomic, readonly) NSDecimalNumber *amount; 15 | @property (nonatomic, copy) AmountUpdateBlock amountUpdatedBlock; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import "AppDelegate.h" 9 | #import "iZettleURLScheme.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 14 | return [[iZettleURLScheme shared] handleOpenURL:url]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Images.xcassets/Wheel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "1x", 6 | "filename" : "wheel~iphone.png" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "2x", 11 | "filename" : "wheel@2x~iphone.png" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "3x", 16 | "filename" : "wheel@3x~iphone.png" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "scale" : "1x", 21 | "filename" : "wheel~ipad.png" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "scale" : "2x", 26 | "filename" : "wheel@2x~ipad.png" 27 | } 28 | ], 29 | "info" : { 30 | "version" : 1, 31 | "author" : "xcode" 32 | } 33 | } -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/ConsoleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ConsoleViewController.m 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import "ConsoleViewController.h" 9 | #import "ViewController.h" 10 | 11 | @interface ConsoleViewController () 12 | @property (weak, nonatomic) IBOutlet UITextView *logTextView; 13 | @end 14 | 15 | @implementation ConsoleViewController 16 | 17 | - (void)viewWillAppear:(BOOL)animated { 18 | [super viewWillAppear:animated]; 19 | self.logTextView.text = _log; 20 | [self.logTextView setContentOffset:CGPointZero animated:YES]; 21 | } 22 | 23 | static NSString *_log; 24 | 25 | - (void)addToLog:(id)object { 26 | if (!_log) { 27 | _log = @""; 28 | } 29 | 30 | NSDate *ts = [NSDate date]; 31 | _log = [NSString stringWithFormat:@"%@\n%@:\n%@\n\n\n%@", ts, NSStringFromClass([object class]), object, _log]; 32 | } 33 | 34 | - (IBAction)done:(id)sender { 35 | [self dismissViewControllerAnimated:YES completion:nil]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "icon120.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "icon180.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "icon76.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "icon152.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleURLName 25 | com.iZettle.url.Sample 26 | CFBundleURLSchemes 27 | 28 | izsample 29 | 30 | 31 | 32 | CFBundleVersion 33 | 1 34 | LSApplicationQueriesSchemes 35 | 36 | izettle 37 | 38 | LSRequiresIPhoneOS 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIMainStoryboardFile~ipad 43 | Main~ipad 44 | UIMainStoryboardFile~iphone 45 | Main~iphone 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | 54 | UISupportedInterfaceOrientations~ipad 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationPortraitUpsideDown 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /iOS Wrapper/README.md: -------------------------------------------------------------------------------- 1 | # URL Scheme Objective C Wrapper 2 | 3 | The iZettleURLScheme is a wrapper around the URL scheme that exposes a simple Objective C API, handling the URL crafting and decomposing for you. 4 | 5 | ## Getting started 6 | 7 | ### Modify your info.plist to enable URL scheme 8 | 9 | CFBundleURLTypes 10 | 11 | 12 | CFBundleURLName 13 | com.yourcompany.yourappname 14 | CFBundleURLSchemes 15 | 16 | yourappurlscheme 17 | 18 | 19 | 20 | 21 | Read more about enabling URL scheme in your app in Apples [Programming Guide](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW2). 22 | 23 | ### Whitelist iZettle URL in your info.plist (iOS9 only) 24 | As of iOS9, apps are required to whitelist URLs queried with `canOpenURL:`. Add `izettle` to the property `LSApplicationQueriesSchemes` in your info.plist. 25 | 26 | ### Add iZettleURLScheme to your project 27 | 28 | Drag iZettleURLScheme.h and iZettleURLScheme.m into your project in XCode. 29 | 30 | ### Implement handling of URL scheme in your AppDelegate 31 | 32 | Import iZettleURLScheme.h to your AppDelegate 33 | 34 | #import "iZettleURLScheme.h" 35 | 36 | The iZettleURLScheme will handle callbacks for you. 37 | 38 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 39 | return [[iZettleURLScheme shared] handleOpenURL:url]; 40 | } 41 | 42 | ### Setup iZettleURLScheme 43 | 44 | If you've only specified one URL in the array, iZettle will call that URL 45 | If you have more than one URL in `CFBundleURLSchemes`, you'll have to specify which one you'd like iZettle to call upon success or failure. 46 | 47 | [iZettleURLScheme shared].callbackURLScheme = @"yourappurlscheme"; 48 | 49 | 50 | ## Operation usage 51 | 52 | **Note** All method calls should go through the singleton returned by `[iZettleURLScheme shared]`. 53 | 54 | To initiate a payment, call: 55 | 56 | - (void)chargeAmount:(NSDecimalNumber *)amount 57 | currency:(NSString *)currency 58 | reference:(NSString *)reference 59 | completion:(void (^)(NSDictionary *paymentInfo, NSError *error))completion; 60 | 61 | To refund a payment, call: 62 | 63 | - (void)refundPaymentWithReference:(NSString *)originalReference 64 | refundReference:(NSString *)refundReference 65 | completion:(void (^)(NSDictionary *paymentInfo, NSError *error))completion; 66 | 67 | To retrive payment info for previous payment, call: 68 | 69 | - (void)retrievePaymentInfoForReference:(NSString *)reference 70 | completion:(iZettleURLSchemeOperationCompletion)completion; 71 | 72 | 73 | For more information about the method arguments and the returned data, please see the [URL Scheme documentation](http://github.com/iZettle/URL-Scheme). -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/AmountWheel.m: -------------------------------------------------------------------------------- 1 | // 2 | // AmountWheel.m 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import "AmountWheel.h" 9 | #import 10 | 11 | @interface RotationGestureRecognizer : UIGestureRecognizer 12 | 13 | @property (nonatomic, assign) CGFloat rotation; 14 | 15 | @end 16 | 17 | @implementation RotationGestureRecognizer 18 | 19 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 20 | if ([[event touchesForGestureRecognizer:self] count] == 1) { 21 | self.state = UIGestureRecognizerStateBegan; 22 | } else { 23 | self.state = UIGestureRecognizerStateFailed; 24 | } 25 | } 26 | 27 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 28 | self.state = UIGestureRecognizerStateChanged; 29 | 30 | UITouch *touch = [touches anyObject]; 31 | 32 | UIView *view = self.view; 33 | CGPoint center = CGPointMake(CGRectGetMidX([view bounds]), CGRectGetMidY([view bounds])); 34 | CGPoint currentTouchPoint = [touch locationInView:view]; 35 | CGPoint previousTouchPoint = [touch previousLocationInView:view]; 36 | 37 | CGFloat angleInRadians = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, previousTouchPoint.x - center.x); 38 | 39 | if (angleInRadians > M_PI) { 40 | angleInRadians -= M_PI; 41 | } 42 | 43 | [self setRotation:angleInRadians]; 44 | } 45 | 46 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 47 | self.state = UIGestureRecognizerStateEnded; 48 | } 49 | 50 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 51 | self.state = UIGestureRecognizerStateCancelled; 52 | } 53 | 54 | @end 55 | 56 | 57 | @implementation AmountWheel { 58 | CGFloat _rotation; 59 | CGFloat _amountIncrementor; 60 | } 61 | 62 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 63 | self = [super initWithCoder:aDecoder]; 64 | if (self) { 65 | _amount = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:1 isNegative:_amountIncrementor < 0]; 66 | RotationGestureRecognizer *rotationGesture = [[RotationGestureRecognizer alloc] initWithTarget:self action:@selector(_rotate:)]; 67 | [self addGestureRecognizer:rotationGesture]; 68 | } 69 | return self; 70 | } 71 | 72 | - (void)_rotate:(RotationGestureRecognizer *)rotationGesture { 73 | if (rotationGesture.rotation < 0 && [_amount isEqual:[NSDecimalNumber zero]]) { 74 | return; 75 | } 76 | 77 | _rotation += rotationGesture.rotation; 78 | self.transform = CGAffineTransformMakeRotation(_rotation); 79 | 80 | _amountIncrementor += rotationGesture.rotation; 81 | if (_amountIncrementor < -0.05 || _amountIncrementor > 0.05) { 82 | NSDecimalNumber *change = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:-1 isNegative:_amountIncrementor < 0]; 83 | _amount = [_amount decimalNumberByAdding:change]; 84 | _amountIncrementor = 0; 85 | if (_amountUpdatedBlock) { 86 | _amountUpdatedBlock(_amount); 87 | } 88 | } 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettleURLScheme/iZettleURLScheme.h: -------------------------------------------------------------------------------- 1 | // 2 | // iZettleURLScheme.h 3 | // iZettle 4 | // 5 | // Copyright (c) 2015 iZettle AB. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @class iZettleURLSchemePaymentInfo; 13 | 14 | typedef void(^iZettleURLSchemeOperationCompletion)(iZettleURLSchemePaymentInfo * __nullable paymentInfo, NSError * __nullable error); 15 | 16 | @interface iZettleURLScheme : NSObject 17 | 18 | @property (nullable, nonatomic, copy) NSString *callbackURLScheme; 19 | @property (nullable, nonatomic, copy) NSString *referralCode; 20 | 21 | /*! If not nil, only an iZettle user with this account will be allowed to be logged in. */ 22 | @property (nullable, nonatomic, copy) NSString *enforcedUserAccount; 23 | 24 | // Called when an operation has to be finished in the iZettle app before continuing. 25 | // Defaults to display an UIAlertView with an action to return to iZettle app. 26 | @property (nullable, nonatomic, copy) dispatch_block_t onOperationAlreadyInProgress; 27 | 28 | @property (nonatomic, assign) BOOL verbose; 29 | 30 | 31 | + (iZettleURLScheme *)shared; 32 | 33 | - (BOOL)handleOpenURL:(NSURL *)url; 34 | 35 | @end 36 | 37 | @interface iZettleURLScheme (Operations) 38 | 39 | /*! Perform a payment with an amount and a reference. */ 40 | - (void)chargeAmount:(NSDecimalNumber *)amount 41 | currency:(nullable NSString *)currency 42 | reference:(nullable NSString *)reference 43 | completion:(iZettleURLSchemeOperationCompletion)completion; 44 | 45 | /*! Refund a payment with a given reference. */ 46 | - (void)refundPaymentWithReference:(NSString *)originalReference 47 | refundReference:(nullable NSString *)refundReference 48 | completion:(iZettleURLSchemeOperationCompletion)completion; 49 | 50 | /*! Query iZettle for payment information of a payment with a given reference. */ 51 | - (void)retrievePaymentInfoForReference:(NSString *)reference 52 | completion:(iZettleURLSchemeOperationCompletion)completion; 53 | 54 | - (void)openIZettleApp; 55 | 56 | /*! Abort any pending operations (opertions will only be locally aborted and the iZettle app won't be notified). */ 57 | - (void)abortPendingOperations; 58 | 59 | @end 60 | 61 | 62 | @interface iZettleURLSchemePaymentInfo : NSObject 63 | 64 | @property (nonatomic, readonly) NSDictionary *dictionary; // Dictionary representation of the payment information 65 | 66 | @property (nonatomic, readonly) NSString *referenceNumber; // iZettles reference to the payment 67 | @property (nonatomic, readonly) NSString *entryMode; // EMV, MAGSTRIPE, MANUAL_ENTRY 68 | @property (nonatomic, readonly) NSString *authorizationCode; 69 | 70 | @property (nonatomic, readonly) NSString *obfuscatedPan; // **** **** **** 1111 71 | @property (nonatomic, readonly) NSString *panHash; // Hash sum of the plain pan 72 | @property (nonatomic, readonly) NSString *cardBrand; 73 | 74 | @property (nonatomic, readonly, nullable) NSString *AID; 75 | @property (nonatomic, readonly, nullable) NSString *TSI; 76 | @property (nonatomic, readonly, nullable) NSString *TVR; 77 | @property (nonatomic, readonly, nullable) NSString *applicationName; 78 | 79 | // Only used for certain markets 80 | @property (nonatomic, readonly, nullable) NSNumber *numberOfInstallments; 81 | @property (nonatomic, readonly, nullable) NSDecimalNumber *installmentAmount; 82 | 83 | @end 84 | 85 | NS_ASSUME_NONNULL_END 86 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // iZettle Wrapper Sample 4 | // 5 | // Copyright (c) 2015 iZettle. All rights reserved. 6 | // 7 | 8 | #import "ViewController.h" 9 | #import "AmountWheel.h" 10 | #import "ConsoleViewController.h" 11 | #import "iZettleURLScheme.h" 12 | 13 | @interface ViewController () 14 | @property (weak, nonatomic) IBOutlet UIButton *chargeButton; 15 | @property (weak, nonatomic) IBOutlet AmountWheel *amountWheel; 16 | @property (weak, nonatomic) IBOutlet UILabel *amountLabel; 17 | @property (weak, nonatomic) IBOutlet UIToolbar *lastPaymentInfoToolBar; 18 | @property (weak, nonatomic) IBOutlet UIView *dotView; 19 | @end 20 | 21 | @implementation ViewController { 22 | iZettleURLSchemePaymentInfo *_lastPaymentInfo; 23 | NSString *_lastReference; 24 | NSDate *_timestamp; 25 | NSError *_lastError; 26 | NSNumberFormatter *_numberFormatter; 27 | } 28 | 29 | #pragma mark - View lifecycle 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | _numberFormatter = [[NSNumberFormatter alloc] init]; 34 | _numberFormatter.minimumFractionDigits = 2; 35 | _numberFormatter.minimumIntegerDigits = 1; 36 | _amountLabel.text = [_numberFormatter stringFromNumber:_amountWheel.amount]; 37 | } 38 | 39 | - (void)viewWillAppear:(BOOL)animated { 40 | [super viewWillAppear:animated]; 41 | _amountWheel.amountUpdatedBlock = ^(NSDecimalNumber *amount) { 42 | _amountLabel.text = [_numberFormatter stringFromNumber:amount]; 43 | }; 44 | } 45 | 46 | - (void)viewWillLayoutSubviews { 47 | [super viewWillLayoutSubviews]; 48 | [self _makeViewRound:_chargeButton]; 49 | [self _makeViewRound:_dotView]; 50 | } 51 | 52 | #pragma mark - User interaction 53 | 54 | - (IBAction)charge:(id)sender { 55 | // Note! Replace this reference with your own if you want to be able to query iZettle about payment info and perform refunds. 56 | _lastReference = [self _uniqueReference]; 57 | NSDecimalNumber *amount = _amountWheel.amount; 58 | 59 | [[iZettleURLScheme shared] chargeAmount:amount currency:nil reference:_lastReference completion:^(iZettleURLSchemePaymentInfo *paymentInfo, NSError *error) { 60 | _lastPaymentInfo = paymentInfo; 61 | _lastError = error; 62 | _timestamp = [NSDate date]; 63 | 64 | [self _updateLastPaymentToolbar]; 65 | [self _showConsole]; 66 | }]; 67 | } 68 | 69 | - (IBAction)openIZettle:(id)sender { 70 | [[iZettleURLScheme shared] openIZettleApp]; 71 | } 72 | 73 | - (IBAction)lastPaymentInfo:(id)sender { 74 | [[iZettleURLScheme shared] retrievePaymentInfoForReference:_lastReference completion:^(iZettleURLSchemePaymentInfo *paymentInfo, NSError *error) { 75 | _lastPaymentInfo = paymentInfo; 76 | _lastError = error; 77 | [self _showConsole]; 78 | }]; 79 | } 80 | 81 | - (IBAction)refundLastPayment:(id)sender { 82 | NSString *paymentReference = _lastReference; 83 | _lastReference = [self _uniqueReference]; 84 | [[iZettleURLScheme shared] refundPaymentWithReference:paymentReference refundReference:_lastReference completion:^(iZettleURLSchemePaymentInfo *paymentInfo, NSError *error) { 85 | _lastPaymentInfo = paymentInfo; 86 | _lastError = error; 87 | [self _showConsole]; 88 | }]; 89 | } 90 | 91 | #pragma mark - Segue handling 92 | 93 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 94 | if ([segue.identifier isEqualToString: @"showConsole"] && sender == self) { 95 | ConsoleViewController *console = (ConsoleViewController *)segue.destinationViewController; 96 | if (_lastError) { 97 | [console addToLog:_lastError]; 98 | } else { 99 | [console addToLog:_lastPaymentInfo]; 100 | } 101 | } 102 | } 103 | 104 | 105 | #pragma mark - Helpers 106 | 107 | - (void)_updateLastPaymentToolbar { 108 | _lastPaymentInfoToolBar.hidden = !(_lastPaymentInfo && _lastPaymentInfo.description); 109 | if (!_lastPaymentInfoToolBar.hidden) { 110 | UIBarButtonItem *lastPaymentButton = [_lastPaymentInfoToolBar.items firstObject]; 111 | NSDateFormatter *dateFormatter = [NSDateFormatter new]; 112 | dateFormatter.dateStyle = NSDateFormatterNoStyle; 113 | dateFormatter.timeStyle = NSDateFormatterMediumStyle; 114 | lastPaymentButton.title = [NSString stringWithFormat:@"Last payment, %@", [dateFormatter stringFromDate:_timestamp]]; 115 | } 116 | } 117 | 118 | - (void)_showConsole { 119 | [self performSegueWithIdentifier:@"showConsole" sender:self]; 120 | } 121 | 122 | - (NSString *)_uniqueReference { 123 | return [[NSUUID UUID] UUIDString]; 124 | } 125 | 126 | - (void)_makeViewRound:(UIView*)aView { 127 | UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:aView.bounds]; 128 | CAShapeLayer *shape = [[CAShapeLayer alloc] init]; 129 | [shape setPath:circlePath.CGPath]; 130 | aView.layer.mask = shape; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettleURLScheme/iZettleURLScheme.m: -------------------------------------------------------------------------------- 1 | // 2 | // iZettleURLScheme.m 3 | // iZettle 4 | // 5 | // Copyright (c) 2015 iZettle AB. All rights reserved. 6 | // 7 | 8 | #import "iZettleURLScheme.h" 9 | #import 10 | 11 | @interface iZettleURLSchemePaymentInfo () 12 | - (id)initWithDictionary:(NSDictionary *)dictionary; 13 | @end 14 | 15 | @interface NSMutableDictionary(AddIfNotNull) 16 | - (void)setValueIfNotNullOrEmpty:(id)value forKey:(NSString *)key; 17 | @end 18 | 19 | @interface NSError (IZErrorSerialization) 20 | + (NSError *)iZettleErrorFromStringRepresentation:(NSString *)string; 21 | @end 22 | 23 | @interface NSString (URLParams) 24 | - (NSString *)stringByAppendingURLParams:(NSDictionary *)params; 25 | - (NSDictionary *)parseURLParams; 26 | @end 27 | 28 | @interface iZettleURLScheme () 29 | 30 | @property (nonatomic, readonly) NSMutableDictionary *pendingCompletions; 31 | 32 | @end 33 | 34 | static NSString * const kXCUHost = @"callback-url"; 35 | static NSString * const kXCUErrorMessage = @"errorMessage"; 36 | 37 | @implementation iZettleURLScheme 38 | 39 | + (iZettleURLScheme *)shared { 40 | static iZettleURLScheme* shared = nil; 41 | static dispatch_once_t once; 42 | dispatch_once(&once, ^{ 43 | shared = [[iZettleURLScheme alloc] init]; 44 | NSArray *urlTypes = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleURLTypes"]; 45 | if (urlTypes.count == 1) { 46 | NSArray *schemes = ((NSDictionary*)urlTypes[0])[@"CFBundleURLSchemes"]; 47 | if (schemes.count == 1) { 48 | shared.callbackURLScheme = schemes[0]; 49 | } 50 | } 51 | shared.onOperationAlreadyInProgress = ^{ 52 | if (shared.verbose) { 53 | NSLog(@"Will display return to iZettle alert."); 54 | } 55 | 56 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Return to iZettle" 57 | message:@"You need to finish your current iZettle operation before continuing." 58 | delegate:shared cancelButtonTitle:@"Cancel" otherButtonTitles:@"Return to iZettle", nil]; 59 | alertView.tag = 2; 60 | [alertView show]; 61 | 62 | }; 63 | 64 | shared->_pendingCompletions = [NSMutableDictionary dictionary]; 65 | 66 | [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note) { 67 | if ([shared.pendingCompletions count] && shared.onOperationAlreadyInProgress) { 68 | shared.onOperationAlreadyInProgress(); 69 | } 70 | }]; 71 | }); 72 | return shared; 73 | } 74 | 75 | - (void)callAction:(NSString *)action withParameters:(NSDictionary *)parameters completion:(iZettleURLSchemeOperationCompletion)completion { 76 | if (!self.callbackURLScheme) { 77 | @throw [NSException exceptionWithName:@"iZettleURLSchemeException" reason:@"Callback URL-Scheme not set" userInfo:nil]; 78 | } 79 | 80 | if (!completion) { 81 | @throw [NSException exceptionWithName:@"iZettleURLSchemeException" reason:@"Completion was nil" userInfo:nil]; 82 | } 83 | 84 | if (self.verbose && self.pendingCompletions.count) { 85 | NSLog(@"Warning: Calling opertion when there are pending operations."); 86 | } 87 | 88 | NSString *urlString = [NSString stringWithFormat:@"izettle://api/%@?", action]; 89 | 90 | if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:urlString]]) { 91 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"iZettle not Installed" 92 | message:@"You need to install the iZettle app from the App Store to be able to proceed." 93 | delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"App Store", nil]; 94 | alertView.tag = 1; 95 | [alertView show]; 96 | if (completion) { 97 | completion(nil, [NSError errorWithDomain:@"com.izettle.url-scheme30.error" code:2 userInfo:@{ NSLocalizedDescriptionKey : @"iZettle app not installed" }]); 98 | } 99 | return; 100 | } 101 | 102 | NSString *operationUUID = [NSUUID UUID].UUIDString; 103 | 104 | NSMutableDictionary *mutableParameters = [parameters mutableCopy]; 105 | 106 | [mutableParameters setValueIfNotNullOrEmpty:self.referralCode forKey:@"referralCode"]; 107 | [mutableParameters setValueIfNotNullOrEmpty:self.enforcedUserAccount forKey:@"enforcedUserAccount"]; 108 | 109 | 110 | mutableParameters[@"successURL"] = [NSString stringWithFormat:@"%@://%@/success?operationUUID=%@", self.callbackURLScheme, kXCUHost, operationUUID]; 111 | mutableParameters[@"failureURL"] = [NSString stringWithFormat:@"%@://%@/failure?operationUUID=%@", self.callbackURLScheme, kXCUHost, operationUUID]; 112 | mutableParameters[@"urlWrapper"] = @"true"; 113 | 114 | self.pendingCompletions[operationUUID] = completion; 115 | 116 | urlString = [urlString stringByAppendingURLParams:mutableParameters]; 117 | 118 | if (_verbose) { 119 | NSLog(@"Action [%@] resolved to URL %@", action, urlString); 120 | } 121 | 122 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]]; 123 | } 124 | 125 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 126 | if (buttonIndex == alertView.firstOtherButtonIndex) { 127 | if (alertView.tag == 1) { 128 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://itunes.apple.com/us/app/apple-store/id447785763?mt=8"]]; 129 | } else { 130 | [self openIZettleApp]; 131 | } 132 | } else { 133 | [self abortPendingOperations]; 134 | } 135 | } 136 | 137 | - (BOOL)handleOpenURL:(NSURL*)url { 138 | if (![url.scheme isEqualToString:self.callbackURLScheme]) { 139 | return NO; 140 | } 141 | 142 | if (![url.host isEqualToString:kXCUHost]) { 143 | return NO; 144 | } 145 | 146 | NSMutableDictionary *params = [[url.query parseURLParams] mutableCopy]; 147 | 148 | NSString *operationUUID = params[@"operationUUID"] ?: @""; 149 | 150 | iZettleURLSchemeOperationCompletion completion = self.pendingCompletions[operationUUID]; 151 | 152 | if (!completion) { 153 | return NO; 154 | } 155 | 156 | [self.pendingCompletions removeObjectForKey:operationUUID]; 157 | 158 | if ([url.path isEqualToString:@"/success"]) { 159 | NSMutableDictionary *info = [params mutableCopy]; 160 | [info removeObjectForKey:@"operationUUID"]; 161 | completion([[iZettleURLSchemePaymentInfo alloc] initWithDictionary:info] , nil); 162 | } else { 163 | NSError *error = [NSError iZettleErrorFromStringRepresentation:params[kXCUErrorMessage]]; 164 | if (!error) { 165 | error = [NSError errorWithDomain:@"com.izettle.url-scheme30.error" 166 | code:3 167 | userInfo:@{ NSLocalizedDescriptionKey : params[kXCUErrorMessage] ?: @"Unknown error" }]; 168 | } 169 | completion(nil, error); 170 | 171 | if ([error.domain isEqualToString:@"com.izettle.session.error"] && error.code == 10 && self.onOperationAlreadyInProgress) { 172 | self.onOperationAlreadyInProgress(); 173 | } 174 | } 175 | 176 | return YES; 177 | } 178 | 179 | @end 180 | 181 | @implementation iZettleURLScheme (Operations) 182 | 183 | - (void)chargeAmount:(NSDecimalNumber *)amount currency:(NSString *)currency reference:(NSString *)reference completion:(iZettleURLSchemeOperationCompletion)completion { 184 | NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; 185 | 186 | [parameters setObject:[amount stringValue] forKey:@"amount"]; 187 | [parameters setValueIfNotNullOrEmpty:currency forKey:@"currency"]; 188 | [parameters setValueIfNotNullOrEmpty:reference forKey:@"reference"]; 189 | 190 | [self callAction:@"payment/charge" withParameters:parameters completion:completion]; 191 | } 192 | 193 | - (void)refundPaymentWithReference:(NSString *)originalReference refundReference:(NSString *)refundReference completion:(iZettleURLSchemeOperationCompletion)completion { 194 | NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; 195 | 196 | [parameters setObject:originalReference forKey:@"originalReference"]; 197 | [parameters setValueIfNotNullOrEmpty:refundReference forKey:@"reference"]; 198 | 199 | [self callAction:@"payment/refund" withParameters:parameters completion:completion]; 200 | } 201 | 202 | - (void)retrievePaymentInfoForReference:(NSString *)reference completion:(iZettleURLSchemeOperationCompletion)completion { 203 | NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; 204 | 205 | [parameters setObject:reference forKey:@"reference"]; 206 | 207 | [self callAction:@"payment/query" withParameters:parameters completion:completion]; 208 | } 209 | 210 | - (void)openIZettleApp { 211 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"izettle://api/open"]]; 212 | } 213 | 214 | - (void)abortPendingOperations { 215 | NSArray *completions = self.pendingCompletions.allValues; 216 | [self.pendingCompletions removeAllObjects]; 217 | for (iZettleURLSchemeOperationCompletion completion in completions) { 218 | completion(nil, [NSError errorWithDomain:@"com.izettle.url-scheme30.error" code:10 userInfo:@{ NSLocalizedDescriptionKey : @"Operation was abandoned" }]); 219 | } 220 | } 221 | 222 | @end 223 | 224 | 225 | @implementation NSString (URLParams) 226 | 227 | - (NSDictionary *)parseURLParams { 228 | NSMutableDictionary *result = [[NSMutableDictionary alloc] init]; 229 | 230 | NSArray *pairs = [self componentsSeparatedByString:@"&"]; 231 | 232 | [pairs enumerateObjectsUsingBlock:^(NSString *pair, NSUInteger idx, BOOL *stop) { 233 | NSArray *comps = [pair componentsSeparatedByString:@"="]; 234 | if ([comps count] == 2) { 235 | [result setObject:[comps[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:comps[0]]; 236 | } 237 | }]; 238 | 239 | return result; 240 | } 241 | 242 | - (NSString *)stringByAppendingURLParams:(NSDictionary *)params { 243 | NSMutableString *result = [NSMutableString stringWithString:self]; 244 | 245 | [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 246 | if ([result rangeOfString:@"?"].location != NSNotFound) { 247 | if (![result hasSuffix:@"&"] && ![result hasSuffix:@"?"]) { 248 | [result appendString:@"&"]; 249 | } 250 | } else { 251 | [result appendString:@"?"]; 252 | } 253 | 254 | NSString *escapedObj = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef)[obj description], NULL, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8)); 255 | [result appendFormat:@"%@=%@", key, escapedObj]; 256 | }]; 257 | 258 | return result; 259 | } 260 | 261 | @end 262 | 263 | @implementation NSMutableDictionary(AddIfNotNull) 264 | 265 | - (void)setValueIfNotNullOrEmpty:(id)value forKey:(NSString *)key { 266 | if (!value || [value isEqual:[NSNull null]] || ([value isKindOfClass:[NSString class]] && ![value length])) 267 | return; 268 | [self setValue:value forKey:key]; 269 | } 270 | 271 | @end 272 | 273 | @implementation NSError (IZErrorSerialization) 274 | 275 | + (NSError *)iZettleErrorFromStringRepresentation:(NSString *)string { 276 | if (!string) return nil; 277 | 278 | NSError *regexError; 279 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^(\\S+)\\((-?\\d+)\\) - (?:(?:(.*) : (.*))|((.*)))$" options:0 error:®exError]; 280 | NSArray *matches = [regex matchesInString:string options:0 range:(NSRange){0, string.length}]; 281 | NSTextCheckingResult *textCheckingResult = matches.firstObject; 282 | if (regexError || matches.count <= 0 || textCheckingResult.numberOfRanges < 3) { 283 | return nil; 284 | } 285 | NSError *underlyingError; 286 | NSInteger messageIndex = 5; 287 | NSRange range = [textCheckingResult rangeAtIndex:4]; 288 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; 289 | if (range.location != NSNotFound) { 290 | underlyingError = [NSError iZettleErrorFromStringRepresentation:[string substringWithRange:range]]; 291 | messageIndex = 3; 292 | } 293 | 294 | [userInfo setValueIfNotNullOrEmpty:[string substringWithRange:[textCheckingResult rangeAtIndex:messageIndex]] forKey:NSLocalizedDescriptionKey]; 295 | [userInfo setValueIfNotNullOrEmpty:underlyingError forKey:NSUnderlyingErrorKey]; 296 | 297 | return [NSError errorWithDomain:[string substringWithRange:[textCheckingResult rangeAtIndex:1]] 298 | code:[[string substringWithRange:[textCheckingResult rangeAtIndex:2]] integerValue] 299 | userInfo:userInfo]; 300 | } 301 | 302 | @end 303 | 304 | 305 | @implementation iZettleURLSchemePaymentInfo { 306 | NSDictionary *_dictionary; 307 | } 308 | 309 | - (id)initWithDictionary:(NSDictionary *)dictionary { 310 | self = [super init]; 311 | if (self) { 312 | _dictionary = [dictionary copy]; 313 | } 314 | return self; 315 | } 316 | 317 | - (NSDictionary *)dictionary { 318 | return _dictionary; 319 | } 320 | 321 | - (NSString *)referenceNumber { 322 | return _dictionary[@"referenceNumber"]; 323 | } 324 | 325 | - (NSNumber *)numberOfInstallments { 326 | return _dictionary[@"numberOfInstallments"]; 327 | } 328 | 329 | - (NSDecimalNumber *)installmentAmount { 330 | return _dictionary[@"installmentAmount"]; 331 | } 332 | 333 | - (NSString *)entryMode { 334 | return _dictionary[@"entryMode"]; 335 | } 336 | 337 | - (NSString *)authorizationCode { 338 | return _dictionary[@"authorizationCode"]; 339 | } 340 | 341 | - (NSString *)obfuscatedPan { 342 | return _dictionary[@"obfuscatedPan"]; 343 | } 344 | 345 | - (NSString *)panHash { 346 | return _dictionary[@"panHash"]; 347 | } 348 | 349 | - (NSString *)cardBrand { 350 | return _dictionary[@"cardBrand"]; 351 | } 352 | 353 | - (NSString *)TVR { 354 | return _dictionary[@"TVR"]; 355 | } 356 | 357 | - (NSString *)TSI { 358 | return _dictionary[@"TSI"]; 359 | } 360 | 361 | - (NSString *)AID { 362 | return _dictionary[@"AID"]; 363 | } 364 | 365 | - (NSString *)applicationName { 366 | return _dictionary[@"applicationName"]; 367 | } 368 | 369 | - (NSString *)description { 370 | return _dictionary.description; 371 | } 372 | 373 | @end 374 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B43DED1A1ACBE89F0091D0E0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B43DED191ACBE89F0091D0E0 /* main.m */; }; 11 | B43DED1D1ACBE89F0091D0E0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B43DED1C1ACBE89F0091D0E0 /* AppDelegate.m */; }; 12 | B43DED201ACBE89F0091D0E0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B43DED1F1ACBE89F0091D0E0 /* ViewController.m */; }; 13 | B43DED251ACBE89F0091D0E0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B43DED241ACBE89F0091D0E0 /* Images.xcassets */; }; 14 | B43DED281ACBE89F0091D0E0 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B43DED261ACBE89F0091D0E0 /* LaunchScreen.xib */; }; 15 | B43DED411ACBE9030091D0E0 /* Main~ipad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B43DED3D1ACBE9030091D0E0 /* Main~ipad.storyboard */; }; 16 | B43DED421ACBE9030091D0E0 /* Main~iphone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B43DED3F1ACBE9030091D0E0 /* Main~iphone.storyboard */; }; 17 | B43DED451ACBE9160091D0E0 /* AmountWheel.m in Sources */ = {isa = PBXBuildFile; fileRef = B43DED441ACBE9160091D0E0 /* AmountWheel.m */; }; 18 | B43DED481ACBE92B0091D0E0 /* ConsoleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B43DED471ACBE92B0091D0E0 /* ConsoleViewController.m */; }; 19 | B43DED531ACBF59A0091D0E0 /* iZettleURLScheme.m in Sources */ = {isa = PBXBuildFile; fileRef = B43DED521ACBF59A0091D0E0 /* iZettleURLScheme.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | B43DED141ACBE89F0091D0E0 /* iZettle Wrapper Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iZettle Wrapper Sample.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | B43DED181ACBE89F0091D0E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25 | B43DED191ACBE89F0091D0E0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 26 | B43DED1B1ACBE89F0091D0E0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 27 | B43DED1C1ACBE89F0091D0E0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 28 | B43DED1E1ACBE89F0091D0E0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 29 | B43DED1F1ACBE89F0091D0E0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 30 | B43DED241ACBE89F0091D0E0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 31 | B43DED271ACBE89F0091D0E0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 32 | B43DED3E1ACBE9030091D0E0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = "Base.lproj/Main~ipad.storyboard"; sourceTree = ""; }; 33 | B43DED401ACBE9030091D0E0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = "Base.lproj/Main~iphone.storyboard"; sourceTree = ""; }; 34 | B43DED431ACBE9160091D0E0 /* AmountWheel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AmountWheel.h; sourceTree = ""; }; 35 | B43DED441ACBE9160091D0E0 /* AmountWheel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AmountWheel.m; sourceTree = ""; }; 36 | B43DED461ACBE92B0091D0E0 /* ConsoleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleViewController.h; sourceTree = ""; }; 37 | B43DED471ACBE92B0091D0E0 /* ConsoleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConsoleViewController.m; sourceTree = ""; }; 38 | B43DED511ACBF59A0091D0E0 /* iZettleURLScheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iZettleURLScheme.h; path = ../../iZettleURLScheme/iZettleURLScheme.h; sourceTree = ""; }; 39 | B43DED521ACBF59A0091D0E0 /* iZettleURLScheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iZettleURLScheme.m; path = ../../iZettleURLScheme/iZettleURLScheme.m; sourceTree = ""; }; 40 | /* End PBXFileReference section */ 41 | 42 | /* Begin PBXFrameworksBuildPhase section */ 43 | B43DED111ACBE89F0091D0E0 /* Frameworks */ = { 44 | isa = PBXFrameworksBuildPhase; 45 | buildActionMask = 2147483647; 46 | files = ( 47 | ); 48 | runOnlyForDeploymentPostprocessing = 0; 49 | }; 50 | /* End PBXFrameworksBuildPhase section */ 51 | 52 | /* Begin PBXGroup section */ 53 | B43DED0B1ACBE89F0091D0E0 = { 54 | isa = PBXGroup; 55 | children = ( 56 | B43DED161ACBE89F0091D0E0 /* iZettle Wrapper Sample */, 57 | B43DED151ACBE89F0091D0E0 /* Products */, 58 | ); 59 | sourceTree = ""; 60 | }; 61 | B43DED151ACBE89F0091D0E0 /* Products */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | B43DED141ACBE89F0091D0E0 /* iZettle Wrapper Sample.app */, 65 | ); 66 | name = Products; 67 | sourceTree = ""; 68 | }; 69 | B43DED161ACBE89F0091D0E0 /* iZettle Wrapper Sample */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | B43DED511ACBF59A0091D0E0 /* iZettleURLScheme.h */, 73 | B43DED521ACBF59A0091D0E0 /* iZettleURLScheme.m */, 74 | B43DED1B1ACBE89F0091D0E0 /* AppDelegate.h */, 75 | B43DED1C1ACBE89F0091D0E0 /* AppDelegate.m */, 76 | B43DED1E1ACBE89F0091D0E0 /* ViewController.h */, 77 | B43DED1F1ACBE89F0091D0E0 /* ViewController.m */, 78 | B43DED461ACBE92B0091D0E0 /* ConsoleViewController.h */, 79 | B43DED471ACBE92B0091D0E0 /* ConsoleViewController.m */, 80 | B43DED431ACBE9160091D0E0 /* AmountWheel.h */, 81 | B43DED441ACBE9160091D0E0 /* AmountWheel.m */, 82 | B43DED241ACBE89F0091D0E0 /* Images.xcassets */, 83 | B43DED261ACBE89F0091D0E0 /* LaunchScreen.xib */, 84 | B43DED3D1ACBE9030091D0E0 /* Main~ipad.storyboard */, 85 | B43DED3F1ACBE9030091D0E0 /* Main~iphone.storyboard */, 86 | B43DED171ACBE89F0091D0E0 /* Supporting Files */, 87 | ); 88 | path = "iZettle Wrapper Sample"; 89 | sourceTree = ""; 90 | }; 91 | B43DED171ACBE89F0091D0E0 /* Supporting Files */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | B43DED181ACBE89F0091D0E0 /* Info.plist */, 95 | B43DED191ACBE89F0091D0E0 /* main.m */, 96 | ); 97 | name = "Supporting Files"; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXNativeTarget section */ 103 | B43DED131ACBE89F0091D0E0 /* iZettle Wrapper Sample */ = { 104 | isa = PBXNativeTarget; 105 | buildConfigurationList = B43DED371ACBE89F0091D0E0 /* Build configuration list for PBXNativeTarget "iZettle Wrapper Sample" */; 106 | buildPhases = ( 107 | B43DED101ACBE89F0091D0E0 /* Sources */, 108 | B43DED111ACBE89F0091D0E0 /* Frameworks */, 109 | B43DED121ACBE89F0091D0E0 /* Resources */, 110 | ); 111 | buildRules = ( 112 | ); 113 | dependencies = ( 114 | ); 115 | name = "iZettle Wrapper Sample"; 116 | productName = "iZettle Wrapper Sample"; 117 | productReference = B43DED141ACBE89F0091D0E0 /* iZettle Wrapper Sample.app */; 118 | productType = "com.apple.product-type.application"; 119 | }; 120 | /* End PBXNativeTarget section */ 121 | 122 | /* Begin PBXProject section */ 123 | B43DED0C1ACBE89F0091D0E0 /* Project object */ = { 124 | isa = PBXProject; 125 | attributes = { 126 | LastUpgradeCheck = 0700; 127 | ORGANIZATIONNAME = iZettle; 128 | TargetAttributes = { 129 | B43DED131ACBE89F0091D0E0 = { 130 | CreatedOnToolsVersion = 6.2; 131 | }; 132 | }; 133 | }; 134 | buildConfigurationList = B43DED0F1ACBE89F0091D0E0 /* Build configuration list for PBXProject "iZettle Wrapper Sample" */; 135 | compatibilityVersion = "Xcode 3.2"; 136 | developmentRegion = English; 137 | hasScannedForEncodings = 0; 138 | knownRegions = ( 139 | en, 140 | Base, 141 | ); 142 | mainGroup = B43DED0B1ACBE89F0091D0E0; 143 | productRefGroup = B43DED151ACBE89F0091D0E0 /* Products */; 144 | projectDirPath = ""; 145 | projectRoot = ""; 146 | targets = ( 147 | B43DED131ACBE89F0091D0E0 /* iZettle Wrapper Sample */, 148 | ); 149 | }; 150 | /* End PBXProject section */ 151 | 152 | /* Begin PBXResourcesBuildPhase section */ 153 | B43DED121ACBE89F0091D0E0 /* Resources */ = { 154 | isa = PBXResourcesBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | B43DED281ACBE89F0091D0E0 /* LaunchScreen.xib in Resources */, 158 | B43DED251ACBE89F0091D0E0 /* Images.xcassets in Resources */, 159 | B43DED411ACBE9030091D0E0 /* Main~ipad.storyboard in Resources */, 160 | B43DED421ACBE9030091D0E0 /* Main~iphone.storyboard in Resources */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXResourcesBuildPhase section */ 165 | 166 | /* Begin PBXSourcesBuildPhase section */ 167 | B43DED101ACBE89F0091D0E0 /* Sources */ = { 168 | isa = PBXSourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | B43DED201ACBE89F0091D0E0 /* ViewController.m in Sources */, 172 | B43DED451ACBE9160091D0E0 /* AmountWheel.m in Sources */, 173 | B43DED531ACBF59A0091D0E0 /* iZettleURLScheme.m in Sources */, 174 | B43DED481ACBE92B0091D0E0 /* ConsoleViewController.m in Sources */, 175 | B43DED1D1ACBE89F0091D0E0 /* AppDelegate.m in Sources */, 176 | B43DED1A1ACBE89F0091D0E0 /* main.m in Sources */, 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | }; 180 | /* End PBXSourcesBuildPhase section */ 181 | 182 | /* Begin PBXVariantGroup section */ 183 | B43DED261ACBE89F0091D0E0 /* LaunchScreen.xib */ = { 184 | isa = PBXVariantGroup; 185 | children = ( 186 | B43DED271ACBE89F0091D0E0 /* Base */, 187 | ); 188 | name = LaunchScreen.xib; 189 | sourceTree = ""; 190 | }; 191 | B43DED3D1ACBE9030091D0E0 /* Main~ipad.storyboard */ = { 192 | isa = PBXVariantGroup; 193 | children = ( 194 | B43DED3E1ACBE9030091D0E0 /* Base */, 195 | ); 196 | name = "Main~ipad.storyboard"; 197 | sourceTree = ""; 198 | }; 199 | B43DED3F1ACBE9030091D0E0 /* Main~iphone.storyboard */ = { 200 | isa = PBXVariantGroup; 201 | children = ( 202 | B43DED401ACBE9030091D0E0 /* Base */, 203 | ); 204 | name = "Main~iphone.storyboard"; 205 | sourceTree = ""; 206 | }; 207 | /* End PBXVariantGroup section */ 208 | 209 | /* Begin XCBuildConfiguration section */ 210 | B43DED351ACBE89F0091D0E0 /* Debug */ = { 211 | isa = XCBuildConfiguration; 212 | buildSettings = { 213 | ALWAYS_SEARCH_USER_PATHS = NO; 214 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 215 | CLANG_CXX_LIBRARY = "libc++"; 216 | CLANG_ENABLE_MODULES = YES; 217 | CLANG_ENABLE_OBJC_ARC = YES; 218 | CLANG_WARN_BOOL_CONVERSION = YES; 219 | CLANG_WARN_CONSTANT_CONVERSION = YES; 220 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 221 | CLANG_WARN_EMPTY_BODY = YES; 222 | CLANG_WARN_ENUM_CONVERSION = YES; 223 | CLANG_WARN_INT_CONVERSION = YES; 224 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 225 | CLANG_WARN_UNREACHABLE_CODE = YES; 226 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 227 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 228 | COPY_PHASE_STRIP = NO; 229 | ENABLE_STRICT_OBJC_MSGSEND = YES; 230 | ENABLE_TESTABILITY = YES; 231 | GCC_C_LANGUAGE_STANDARD = gnu99; 232 | GCC_DYNAMIC_NO_PIC = NO; 233 | GCC_OPTIMIZATION_LEVEL = 0; 234 | GCC_PREPROCESSOR_DEFINITIONS = ( 235 | "DEBUG=1", 236 | "$(inherited)", 237 | ); 238 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 239 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 240 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 241 | GCC_WARN_UNDECLARED_SELECTOR = YES; 242 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 243 | GCC_WARN_UNUSED_FUNCTION = YES; 244 | GCC_WARN_UNUSED_VARIABLE = YES; 245 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 246 | MTL_ENABLE_DEBUG_INFO = YES; 247 | ONLY_ACTIVE_ARCH = YES; 248 | SDKROOT = iphoneos; 249 | TARGETED_DEVICE_FAMILY = "1,2"; 250 | }; 251 | name = Debug; 252 | }; 253 | B43DED361ACBE89F0091D0E0 /* Release */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | ALWAYS_SEARCH_USER_PATHS = NO; 257 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 258 | CLANG_CXX_LIBRARY = "libc++"; 259 | CLANG_ENABLE_MODULES = YES; 260 | CLANG_ENABLE_OBJC_ARC = YES; 261 | CLANG_WARN_BOOL_CONVERSION = YES; 262 | CLANG_WARN_CONSTANT_CONVERSION = YES; 263 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INT_CONVERSION = YES; 267 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 268 | CLANG_WARN_UNREACHABLE_CODE = YES; 269 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 270 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 271 | COPY_PHASE_STRIP = NO; 272 | ENABLE_NS_ASSERTIONS = NO; 273 | ENABLE_STRICT_OBJC_MSGSEND = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 276 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 277 | GCC_WARN_UNDECLARED_SELECTOR = YES; 278 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 279 | GCC_WARN_UNUSED_FUNCTION = YES; 280 | GCC_WARN_UNUSED_VARIABLE = YES; 281 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 282 | MTL_ENABLE_DEBUG_INFO = NO; 283 | SDKROOT = iphoneos; 284 | TARGETED_DEVICE_FAMILY = "1,2"; 285 | VALIDATE_PRODUCT = YES; 286 | }; 287 | name = Release; 288 | }; 289 | B43DED381ACBE89F0091D0E0 /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 293 | INFOPLIST_FILE = "iZettle Wrapper Sample/Info.plist"; 294 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 295 | PRODUCT_BUNDLE_IDENTIFIER = com.izettle.sample; 296 | PRODUCT_NAME = "$(TARGET_NAME)"; 297 | }; 298 | name = Debug; 299 | }; 300 | B43DED391ACBE89F0091D0E0 /* Release */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 304 | INFOPLIST_FILE = "iZettle Wrapper Sample/Info.plist"; 305 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 306 | PRODUCT_BUNDLE_IDENTIFIER = com.izettle.sample; 307 | PRODUCT_NAME = "$(TARGET_NAME)"; 308 | }; 309 | name = Release; 310 | }; 311 | /* End XCBuildConfiguration section */ 312 | 313 | /* Begin XCConfigurationList section */ 314 | B43DED0F1ACBE89F0091D0E0 /* Build configuration list for PBXProject "iZettle Wrapper Sample" */ = { 315 | isa = XCConfigurationList; 316 | buildConfigurations = ( 317 | B43DED351ACBE89F0091D0E0 /* Debug */, 318 | B43DED361ACBE89F0091D0E0 /* Release */, 319 | ); 320 | defaultConfigurationIsVisible = 0; 321 | defaultConfigurationName = Release; 322 | }; 323 | B43DED371ACBE89F0091D0E0 /* Build configuration list for PBXNativeTarget "iZettle Wrapper Sample" */ = { 324 | isa = XCConfigurationList; 325 | buildConfigurations = ( 326 | B43DED381ACBE89F0091D0E0 /* Debug */, 327 | B43DED391ACBE89F0091D0E0 /* Release */, 328 | ); 329 | defaultConfigurationIsVisible = 0; 330 | defaultConfigurationName = Release; 331 | }; 332 | /* End XCConfigurationList section */ 333 | }; 334 | rootObject = B43DED0C1ACBE89F0091D0E0 /* Project object */; 335 | } 336 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Base.lproj/Main~ipad.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 80 | 86 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /iOS Wrapper/iZettle Wrapper Sample/iZettle Wrapper Sample/Base.lproj/Main~iphone.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 73 | 79 | 85 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | --------------------------------------------------------------------------------