UNPKG

@monoku/react-native-payments-stripe

Version:

React Native Payments add-on for processing payments with Stripe.

266 lines (167 loc) 5.7 kB
# Stripe iOS Objective-C Style Guide ## Ground Rules ### Spacing - Indent using 4 spaces. No tabs. - Avoid starting methods with an empty line - There should not be a need to use multiple consecutive empty lines - Asterisks should be attached to the variable name `NSString *text` unless it's `NSString * const Text` ### Variable Naming - Lean towards clarity over compactness - Avoid single letter variables. Try using `idx` / `jdx` instead of `i` / `j` in for loops. - Prefer `urlString` over `URLString` (acronym prefix), `baseUrlString` over `baseURLString` (acronym infix), and `stripeId` over `stripeID` (acronym suffix) ### Control Flow - Place `else if` and `else` on their own lines: ```objc if (condition) { // A } else if (condition) { // B } else { // C } ``` - Always wrap conditional bodies with curly braces - Use ternary operators sparingly and for simple conditions only: ```objc type = isCard ? @"card" : @"unknown"; type = dictionary[@"type"] ?: @"default"; ``` ### Documentation - Document using the multi-line syntax in all cases with the content aligned with the first asterisk: ```objc /** This is a one line description for a simple method */ - (void)title; /** This is a multi-line description for a complicated method @param @see https://... */ - (void)title; ``` ### Literals - Use literals to create immutable instances of `NSString`, `NSDictionary`, `NSArray`, `NSNumber`: ```objc NSArray *brands = @[@"visa", @"mastercard", @"discover"]; NSDictionary *parameters = @{ @"currency": @"usd", @"amount": @1000, }; ``` - Dictionary colons should be attached to the key - Align multi-line literals using default Xcode indentation ### Constants - Use static constants whenever appropriate. Names should start with a capital letter: ```objc static NSString * const HTTPMethodGET = @"GET"; static const CGFloat ButtonHeight = 100.0; ``` - Any public static constants should be prefixed with `STP`: ```objc static NSString * const STPSDKVersion = @"11.0.0"; ``` ### Folders - We use flat folder structure on disk with some exceptions - Save files to the appropriate root level folder. Typical folders include: - `stripe-ios/Stripe/` - `stripe-ios/Tests/Tests/` - `stripe-ios/Example/Stripe iOS Example (Simple)/` - `stripe-ios/Example/Stripe iOS Example (Custom)/` - Save public header files in `stripe-ios/Stripe/PublicHeaders/` for Cocoapods compatibility ## Design Patterns ### Imports - Ordering for imports in headers - Import system frameworks - Import superclasses and protocols sorted alphabetically - Use `@class` for everything else ```objc #import <Foundation/Foundation.h> #import "STPAPIResponseDecodable.h" #import "STPBankAccountParams.h" @class STPAddress, @STPToken; ``` - Ordering for imports in implementations - Import system frameworks - Import corresponding headers - Import everything else sorted alphabetically ```objc #import <PassKit/PassKit.h> #import "STPSource.h" #import "STPSource+Private.h" #import "NSDictionary+Stripe.h" #import "STPSourceOwner.h" #import "STPSourceReceiver.h" #import "STPSourceRedirect.h" #import "STPSourceVerification.h" ``` ### Interfaces and Protocols - Stick to Xcode default spacing for interfaces, categories, and protocols - Always define `NS_ASSUME_NON_NULL_BEGIN` / `NS_ASSUME_NON_NULL_END` in headers ```objc NS_ASSUME_NON_NULL_BEGIN @protocol STPSourceProtocol <NSObject> // ... @end // ... @interface STPSource : NSObject<STPAPIResponseDecodable, STPSourceProtocol> // ... @end // ... @interface STPSource () <STPInternalAPIResponseDecodable> // ... @end NS_ASSUME_NON_NULL_END ``` - Category methods on certain classes need to be prefixed with `stp_` to avoid collision: ``` // NSDictionary+Stripe.h @interface NSDictionary (Stripe) - (NSDictionary *)stp_jsonDictionary; @end ``` - Define private properties and methods as class extensions inside the implementation. Ex: `STPSource.m`. - Define internal properties and methods as class extensions inside a `+Private.h` file. Ex: `STPSource+Private.h`. - Access private properties and methods from test classes by defining a class extension inside the test implementation: ``` // STPBankAccountTest.m @interface STPBankAccount () + (STPBankAccountStatus)statusFromString:(NSString *)string; + (NSString *)stringFromStatus:(STPBankAccountStatus)status; @end @interface STPBankAccountTest : XCTestCase @end @implementation STPBankAccountTest // ... @end ``` ### Properties - Properties should be defined using this syntax: ``` @property (<nonatomic / atomic>, <weak / copy / strong>, <nullable / _>, <readonly / readwrite>) <class> *<name>; @property (<nonatomic / atomic>, <assign>, <readonly / readwrite>) <type> <name>; ``` - Use `copy` for classes with mutable counterparts such as `NSString`, `NSArray`, `NSDictionary` - Leverage auto property synthesis whenever possible - Declare `@synthesize` and `@dynamic` on separate lines for shorter diffs ### Init ```objc - (instancetype)init { self = [super init]; if (self) { // ... } return self; } ``` ### Methods - See [Coding Guidelines for Cocoa - Naming Methods](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-BCIGIJJF) ### Implementation - Use `#pragma mark - <text>` and `#pragma mark <text>` to group methods In large implementation files: ```objc #pragma mark - Button Handlers #pragma mark - UITableViewDataSource #pragma mark - UITableViewDelegate ```