├── SimpleCode ├── .DS_Store ├── BlueLibrary-Objc │ ├── BlueLibrary │ │ ├── en.lproj │ │ │ └── InfoPlist.strings │ │ ├── Default.png │ │ ├── Default@2x.png │ │ ├── Default-568h@2x.png │ │ ├── ViewController.h │ │ ├── AlbumView.h │ │ ├── Album+TableRepresentation.h │ │ ├── BlueLibrary-Prefix.pch │ │ ├── main.m │ │ ├── HTTPClient.h │ │ ├── AppDelegate.h │ │ ├── Album.h │ │ ├── LibraryAPI.h │ │ ├── Album+TableRepresentation.m │ │ ├── PersistencyManager.h │ │ ├── HTTPClient.m │ │ ├── HorizontalScroller.h │ │ ├── BlueLibrary-Info.plist │ │ ├── Album.m │ │ ├── AlbumView.m │ │ ├── AppDelegate.m │ │ ├── LibraryAPI.m │ │ ├── PersistencyManager.m │ │ ├── HorizontalScroller.m │ │ └── ViewController.m │ ├── .DS_Store │ └── BlueLibrary.xcodeproj │ │ ├── xcuserdata │ │ ├── admin.xcuserdatad │ │ │ ├── xcdebugger │ │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ │ ├── xcschememanagement.plist │ │ │ │ └── BlueLibrary.xcscheme │ │ └── eli.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── BlueLibrary.xcscheme │ │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcuserdata │ │ │ ├── eli.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── admin.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcshareddata │ │ │ └── BlueLibrary.xccheckout │ │ └── project.pbxproj └── BlueLibrary-Swift │ ├── .DS_Store │ ├── BlueLibrarySwift.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── admin.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcuserdata │ │ └── admin.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── BlueLibrarySwift.xcscheme │ └── project.pbxproj │ ├── BlueLibrarySwiftTests │ ├── Info.plist │ └── BlueLibrarySwiftTests.swift │ └── BlueLibrarySwift │ ├── AlbumExtensions.swift │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── HTTPClient.swift │ ├── Info.plist │ ├── Album.swift │ ├── AlbumView.swift │ ├── AppDelegate.swift │ ├── LibraryAPI.swift │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── PersistencyManager.swift │ ├── HorizontalScroller.swift │ └── ViewController.swift ├── LICENSE └── README.md /SimpleCode/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/.DS_Store -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Objc/.DS_Store -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Swift/.DS_Store -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Objc/BlueLibrary/Default.png -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Objc/BlueLibrary/Default@2x.png -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Objc/BlueLibrary/Default-568h@2x.png -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/xcuserdata/admin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/project.xcworkspace/xcuserdata/eli.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/project.xcworkspace/xcuserdata/eli.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // BlueLibrary 4 | // 5 | // Created by Eli Ganem on 31/7/13. 6 | // Copyright (c) 2013 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyming/Trip-to-iOS-Design-Patterns/HEAD/SimpleCode/BlueLibrary-Swift/BlueLibrarySwift.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/AlbumView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumView.h 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AlbumView : UIView 12 | - (id)initWithFrame:(CGRect)frame albumCover:(NSString*)albumCover; 13 | @end 14 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/Album+TableRepresentation.h: -------------------------------------------------------------------------------- 1 | // 2 | // Album+TableRepresentation.h 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "Album.h" 10 | 11 | @interface Album (TableRepresentation) 12 | 13 | - (NSDictionary*)tr_tableRepresentation; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/BlueLibrary-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'BlueLibrary' target in the 'BlueLibrary' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BlueLibrary 4 | // 5 | // Created by Eli Ganem on 31/7/13. 6 | // Copyright (c) 2013 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/HTTPClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // HTTPClient.h 3 | // MyLibrary 4 | // 5 | // Created by Eli Ganem on 8/7/13. 6 | // Copyright (c) 2013 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HTTPClient : NSObject 12 | 13 | - (id)getRequest:(NSString*)url; 14 | - (id)postRequest:(NSString*)url body:(NSString*)body; 15 | - (UIImage*)downloadImage:(NSString*)url; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // BlueLibrary 4 | // 5 | // Created by Eli Ganem on 31/7/13. 6 | // Copyright (c) 2013 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ViewController; 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) ViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/Album.h: -------------------------------------------------------------------------------- 1 | // 2 | // Album.h 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Album : NSObject 12 | @property (nonatomic, copy, readonly) NSString *title, *artist, *genre, *coverUrl, *year; 13 | - (id)initWithTitle:(NSString*)title artist:(NSString*)artist coverUrl:(NSString*)coverUrl year:(NSString*)year; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/LibraryAPI.h: -------------------------------------------------------------------------------- 1 | // 2 | // LibraryAPI.h 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | @class Album; 11 | 12 | @interface LibraryAPI : NSObject 13 | + (LibraryAPI*)sharedInstance; 14 | 15 | - (NSArray*)getAlbums; 16 | - (void)addAlbum:(Album*)album atIndex:(NSInteger)index; 17 | - (void)deleteAlbumAtIndex:(NSInteger)index; 18 | 19 | - (void)saveAlbums; 20 | @end 21 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/Album+TableRepresentation.m: -------------------------------------------------------------------------------- 1 | // 2 | // Album+TableRepresentation.m 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "Album+TableRepresentation.h" 10 | 11 | @implementation Album (TableRepresentation) 12 | 13 | - (NSDictionary*)tr_tableRepresentation 14 | { 15 | return @{@"titles":@[@"Artist", @"Album", @"Genre", @"Year"], 16 | @"values":@[self.artist, self.title, self.genre, self.year]}; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/PersistencyManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // PersistencyManager.h 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | @class Album; 11 | 12 | @interface PersistencyManager : NSObject 13 | 14 | - (NSArray*)getAlbums; 15 | - (void)addAlbum:(Album*)album atIndex:(NSInteger)index; 16 | - (void)deleteAlbumAtIndex:(NSInteger)index; 17 | 18 | - (void)saveImage:(UIImage*)image filename:(NSString*)filename; 19 | - (UIImage*)getImage:(NSString*)filename; 20 | 21 | - (void)saveAlbums; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/HTTPClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // HTTPClient.m 3 | // MyLibrary 4 | // 5 | // Created by Eli Ganem on 8/7/13. 6 | // Copyright (c) 2013 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "HTTPClient.h" 10 | 11 | @implementation HTTPClient 12 | 13 | - (id)getRequest:(NSString*)url 14 | { 15 | return nil; 16 | } 17 | 18 | - (id)postRequest:(NSString*)url body:(NSString*)body 19 | { 20 | return nil; 21 | } 22 | 23 | - (UIImage*)downloadImage:(NSString*)url 24 | { 25 | NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 26 | return [UIImage imageWithData:data]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BlueLibrary.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 450EECBB17A9B03A00957F62 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/xcuserdata/eli.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BlueLibrary.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 450EECBB17A9B03A00957F62 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BlueLibrarySwift.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 101DD6C41A052EDE00161F0D 16 | 17 | primary 18 | 19 | 20 | 101DD6D91A052EDE00161F0D 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwiftTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.Raywenderlich.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwiftTests/BlueLibrarySwiftTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueLibrarySwiftTests.swift 3 | // BlueLibrarySwiftTests 4 | // 5 | // Created by Vincent Ngo on 11/1/14. 6 | // Copyright (c) 2014 Raywenderlich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class BlueLibrarySwiftTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Baoming Bai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/HorizontalScroller.h: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalScroller.h 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import 10 | @class HorizontalScroller; 11 | 12 | 13 | @protocol HorizontalScrollerDelegate 14 | 15 | @required 16 | 17 | // ask the delegate how many views he wants to present inside the horizontal scroller 18 | - (NSInteger)numberOfViewsForHorizontalScroller:(HorizontalScroller*)scroller; 19 | 20 | // ask the delegate to return the view that should appear at 21 | - (UIView*)horizontalScroller:(HorizontalScroller*)scroller viewAtIndex:(int)index; 22 | 23 | // inform the delegate what the view at has been clicked 24 | - (void)horizontalScroller:(HorizontalScroller*)scroller clickedViewAtIndex:(int)index; 25 | 26 | @optional 27 | 28 | // ask the delegate for the index of the initial view to display. this method is optional 29 | // and defaults to 0 if it's not implemented by the delegate 30 | - (NSInteger)initialViewIndexForHorizontalScroller:(HorizontalScroller*)scroller; 31 | @end 32 | 33 | @interface HorizontalScroller : UIView 34 | 35 | @property(nonatomic,weak) id delegate; 36 | 37 | - (void)reload; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/BlueLibrary-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.movingapp.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/AlbumExtensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import Foundation 24 | 25 | extension Album { 26 | func ae_tableRepresentation() -> (titles:[String], values:[String]) { 27 | return (["Artist", "Album", "Genre", "Year"], [artist, title, genre, year]) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/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 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/Album.m: -------------------------------------------------------------------------------- 1 | // 2 | // Album.m 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "Album.h" 10 | 11 | @implementation Album 12 | - (id)initWithTitle:(NSString*)title artist:(NSString*)artist coverUrl:(NSString*)coverUrl 13 | year:(NSString*)year { 14 | self = [super init]; 15 | if (self) 16 | { 17 | _title = title; 18 | _artist = artist; 19 | _coverUrl = coverUrl; 20 | _year = year; 21 | _genre = @"Pop"; 22 | } 23 | return self; 24 | } 25 | - (void)encodeWithCoder:(NSCoder *)aCoder 26 | 27 | { 28 | 29 | [aCoder encodeObject:self.year forKey:@"year"]; 30 | 31 | [aCoder encodeObject:self.title forKey:@"album"]; 32 | 33 | [aCoder encodeObject:self.artist forKey:@"artist"]; 34 | 35 | [aCoder encodeObject:self.coverUrl forKey:@"cover_url"]; 36 | 37 | [aCoder encodeObject:self.genre forKey:@"genre"]; 38 | 39 | } 40 | 41 | - (id)initWithCoder:(NSCoder *)aDecoder 42 | 43 | { 44 | 45 | self = [super init]; 46 | 47 | if (self) 48 | 49 | { 50 | 51 | _year = [aDecoder decodeObjectForKey:@"year"]; 52 | 53 | _title = [aDecoder decodeObjectForKey:@"album"]; 54 | 55 | _artist = [aDecoder decodeObjectForKey:@"artist"]; 56 | 57 | _coverUrl = [aDecoder decodeObjectForKey:@"cover_url"]; 58 | 59 | _genre = [aDecoder decodeObjectForKey:@"genre"]; 60 | 61 | } 62 | 63 | return self; 64 | 65 | } 66 | @end 67 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/HTTPClient.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | class HTTPClient { 26 | 27 | func getRequest(url: String) -> (AnyObject) { 28 | return NSData() 29 | } 30 | 31 | func postRequest(url: String, body: String) -> (AnyObject){ 32 | return NSData() 33 | } 34 | 35 | func downloadImage(url: String) -> (UIImage) { 36 | let aUrl = NSURL(string: url) 37 | var data = NSData(contentsOfURL: aUrl!) 38 | let image = UIImage(data: data!) 39 | return image! 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.Raywenderlich.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/project.xcworkspace/xcshareddata/BlueLibrary.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | E562A06A-8887-4E5F-BFA3-78970FA8B2B8 9 | IDESourceControlProjectName 10 | BlueLibrary 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 3F3A5B49A0CCC5847DBFA831C3BE0F97C5858CA1 14 | github.com:skyming/Trip-to-IOS-Design-Patterns.git 15 | 16 | IDESourceControlProjectPath 17 | SimpleCode/BlueLibrary/BlueLibrary.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 3F3A5B49A0CCC5847DBFA831C3BE0F97C5858CA1 21 | ../../../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:skyming/Trip-to-IOS-Design-Patterns.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 3F3A5B49A0CCC5847DBFA831C3BE0F97C5858CA1 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 3F3A5B49A0CCC5847DBFA831C3BE0F97C5858CA1 36 | IDESourceControlWCCName 37 | Trip-to-IOS-Design-Patterns 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/AlbumView.m: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumView.m 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "AlbumView.h" 10 | 11 | @implementation AlbumView 12 | { 13 | UIImageView *coverImage; 14 | UIActivityIndicatorView *indicator; 15 | } 16 | 17 | - (id)initWithFrame:(CGRect)frame albumCover:(NSString*)albumCover 18 | { 19 | self = [super initWithFrame:frame]; 20 | if (self) 21 | { 22 | 23 | self.backgroundColor = [UIColor blackColor]; 24 | // the coverImage has a 5 pixels margin from its frame 25 | coverImage = [[UIImageView alloc] initWithFrame:CGRectMake(5,5,frame.size.width-10,frame.size.height-10)]; 26 | [self addSubview:coverImage]; 27 | 28 | indicator = [[UIActivityIndicatorView alloc] init]; 29 | indicator.center = self.center; 30 | indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; 31 | [indicator startAnimating]; 32 | [self addSubview:indicator]; 33 | 34 | [coverImage addObserver:self forKeyPath:@"image" options:0 context:nil]; 35 | [[NSNotificationCenter defaultCenter] postNotificationName:@"BLDownloadImageNotification" 36 | object:self 37 | userInfo:@{@"imageView":coverImage, @"coverUrl":albumCover}]; 38 | 39 | // NSLog(@"Post 内存:%p %p",coverImage,coverImage.image); 40 | 41 | } 42 | return self; 43 | } 44 | - (void)dealloc 45 | { 46 | [coverImage removeObserver:self forKeyPath:@"image"]; 47 | } 48 | 49 | 50 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 51 | { 52 | if ([keyPath isEqualToString:@"image"]) 53 | { 54 | [indicator stopAnimating]; 55 | } 56 | } 57 | 58 | /* 59 | // Only override drawRect: if you perform custom drawing. 60 | // An empty implementation adversely affects performance during animation. 61 | - (void)drawRect:(CGRect)rect { 62 | // Drawing code 63 | } 64 | */ 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // BlueLibrary 4 | // 5 | // Created by Eli Ganem on 31/7/13. 6 | // Copyright (c) 2013 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | #import "ViewController.h" 12 | 13 | @implementation AppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | 18 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 19 | // Override point for customization after application launch. 20 | self.viewController = [[ViewController alloc] init]; 21 | self.window.rootViewController = self.viewController; 22 | [self.window makeKeyAndVisible]; 23 | return YES; 24 | } 25 | 26 | - (void)applicationWillResignActive:(UIApplication *)application 27 | { 28 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 29 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 30 | } 31 | 32 | - (void)applicationDidEnterBackground:(UIApplication *)application 33 | { 34 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | - (void)applicationWillEnterForeground:(UIApplication *)application 39 | { 40 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 41 | } 42 | 43 | - (void)applicationDidBecomeActive:(UIApplication *)application 44 | { 45 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 46 | } 47 | 48 | - (void)applicationWillTerminate:(UIApplication *)application 49 | { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/Album.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | class Album: NSObject, NSCoding { 26 | var title : String! 27 | var artist : String! 28 | var genre : String! 29 | var coverUrl : String! 30 | var year : String! 31 | 32 | init(title: String, artist: String, genre: String, coverUrl: String, year: String) { 33 | super.init() 34 | 35 | self.title = title 36 | self.artist = artist 37 | self.genre = genre 38 | self.coverUrl = coverUrl 39 | self.year = year 40 | } 41 | 42 | required init(coder decoder: NSCoder) { 43 | super.init() 44 | self.title = decoder.decodeObjectForKey("title") as String? 45 | self.artist = decoder.decodeObjectForKey("artist") as String? 46 | self.genre = decoder.decodeObjectForKey("genre") as String? 47 | self.coverUrl = decoder.decodeObjectForKey("cover_url") as String? 48 | self.year = decoder.decodeObjectForKey("year") as String? 49 | } 50 | 51 | func encodeWithCoder(aCoder: NSCoder) { 52 | aCoder.encodeObject(title, forKey: "title") 53 | aCoder.encodeObject(artist, forKey: "artist") 54 | aCoder.encodeObject(genre, forKey: "genre") 55 | aCoder.encodeObject(coverUrl, forKey: "cover_url") 56 | aCoder.encodeObject(year, forKey: "year") 57 | } 58 | 59 | func description() -> String { 60 | return "title: \(title)" + 61 | "artist: \(artist)" + 62 | "genre: \(genre)" + 63 | "coverUrl: \(coverUrl)" + 64 | "year: \(year)" 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/AlbumView.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | class AlbumView: UIView { 26 | 27 | private let coverImage: UIImageView! 28 | private let indicator: UIActivityIndicatorView! 29 | 30 | required init(coder aDecoder: NSCoder) { 31 | super.init(coder: aDecoder) 32 | } 33 | 34 | init(frame: CGRect, albumCover: String) { 35 | super.init(frame: frame) 36 | backgroundColor = UIColor.blackColor() 37 | coverImage = UIImageView(frame: CGRectMake(5, 5, frame.size.width - 10, frame.size.height - 10)) 38 | addSubview(coverImage) 39 | coverImage.addObserver(self, forKeyPath: "image", options: nil, context: nil) 40 | 41 | indicator = UIActivityIndicatorView() 42 | indicator.center = center 43 | indicator.activityIndicatorViewStyle = .WhiteLarge 44 | indicator.startAnimating() 45 | addSubview(indicator) 46 | 47 | NSNotificationCenter.defaultCenter().postNotificationName("BLDownloadImageNotification", object: self, userInfo: ["imageView":coverImage, "coverUrl" : albumCover]) 48 | } 49 | 50 | deinit { 51 | coverImage.removeObserver(self, forKeyPath: "image") 52 | } 53 | 54 | override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer) { 55 | if keyPath == "image" { 56 | indicator.stopAnimating() 57 | } 58 | } 59 | 60 | func highlightAlbum(#didHighlightView: Bool) { 61 | if didHighlightView == true { 62 | backgroundColor = UIColor.whiteColor() 63 | } else { 64 | backgroundColor = UIColor.blackColor() 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | @UIApplicationMain 26 | class AppDelegate: UIResponder, UIApplicationDelegate { 27 | 28 | var window: UIWindow? 29 | 30 | 31 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 32 | // Override point for customization after application launch. 33 | return true 34 | } 35 | 36 | func applicationWillResignActive(application: UIApplication) { 37 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 38 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 39 | } 40 | 41 | func applicationDidEnterBackground(application: UIApplication) { 42 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 44 | } 45 | 46 | func applicationWillEnterForeground(application: UIApplication) { 47 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | } 49 | 50 | func applicationDidBecomeActive(application: UIApplication) { 51 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 52 | } 53 | 54 | func applicationWillTerminate(application: UIApplication) { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | 59 | } 60 | 61 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/LibraryAPI.m: -------------------------------------------------------------------------------- 1 | // 2 | // LibraryAPI.m 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "LibraryAPI.h" 10 | #import "Album.h" 11 | #import "PersistencyManager.h" 12 | #import "HTTPClient.h" 13 | 14 | @interface LibraryAPI () { 15 | PersistencyManager *persistencyManager; 16 | HTTPClient *httpClient; 17 | BOOL isOnline; 18 | 19 | } 20 | @end 21 | 22 | @implementation LibraryAPI 23 | + (LibraryAPI*)sharedInstance 24 | { 25 | // 1 26 | static LibraryAPI *_sharedInstance = nil; 27 | 28 | // 2 29 | static dispatch_once_t oncePredicate; 30 | 31 | // 3 32 | dispatch_once(&oncePredicate, ^{ 33 | _sharedInstance = [[LibraryAPI alloc] init]; 34 | }); 35 | return _sharedInstance; 36 | } 37 | 38 | - (id)init{ 39 | self = [super init]; 40 | 41 | if (self) { 42 | 43 | persistencyManager = [[PersistencyManager alloc] init]; 44 | 45 | httpClient = [[HTTPClient alloc] init]; 46 | 47 | isOnline = NO; 48 | 49 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadImage:) name:@"BLDownloadImageNotification" object:nil]; 50 | } 51 | 52 | return self; 53 | 54 | } 55 | - (void)dealloc 56 | { 57 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 58 | 59 | } 60 | 61 | 62 | -(NSArray*)getAlbums 63 | { 64 | return [persistencyManager getAlbums]; 65 | } 66 | 67 | - (void)addAlbum:(Album*)album atIndex:(NSInteger)index 68 | { 69 | [persistencyManager addAlbum:album atIndex:index]; 70 | 71 | if (isOnline) 72 | { 73 | [httpClient postRequest:@"/api/addAlbum" body:[album description]]; 74 | } 75 | 76 | } 77 | 78 | - (void)deleteAlbumAtIndex:(NSInteger)index 79 | { 80 | [persistencyManager deleteAlbumAtIndex:index]; 81 | 82 | if (isOnline) 83 | { 84 | [httpClient postRequest:@"/api/deleteAlbum" body:[@(index) description]]; 85 | } 86 | 87 | } 88 | 89 | - (void)downloadImage:(NSNotification*)notification 90 | { 91 | 92 | // 1 93 | UIImageView *imageView = notification.userInfo[@"imageView"]; 94 | NSString *coverUrl = notification.userInfo[@"coverUrl"]; 95 | 96 | // 2 97 | imageView.image = [persistencyManager getImage:[coverUrl lastPathComponent]]; 98 | if (imageView.image == nil) 99 | { 100 | // 3 101 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 102 | 103 | UIImage *image = [httpClient downloadImage:coverUrl]; 104 | 105 | // 4 106 | dispatch_sync(dispatch_get_main_queue(), ^{ 107 | imageView.image = image; 108 | [persistencyManager saveImage:image filename:[coverUrl lastPathComponent]]; 109 | // NSLog(@"Add 内存:%p %p",imageView,imageView.image); 110 | }); 111 | 112 | 113 | }); 114 | } 115 | } 116 | 117 | - (void)saveAlbums 118 | { 119 | [persistencyManager saveAlbums]; 120 | } 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/PersistencyManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // PersistencyManager.m 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "PersistencyManager.h" 10 | #import "Album.h" 11 | 12 | @interface PersistencyManager () { 13 | // an array of all albums 14 | NSMutableArray *albums; 15 | } 16 | 17 | @end 18 | 19 | @implementation PersistencyManager 20 | 21 | - (id)init 22 | 23 | { 24 | 25 | self = [super init]; 26 | 27 | if (self) { 28 | 29 | NSData *data = [NSData dataWithContentsOfFile:[NSHomeDirectory() stringByAppendingString:@"/Documents/albums.bin"]]; 30 | albums = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 31 | 32 | if (albums == nil) 33 | { 34 | albums = [NSMutableArray arrayWithArray: 35 | @[[[Album alloc] initWithTitle:@"Best of Bowie" artist:@"David Bowie" coverUrl:@"http://b.hiphotos.baidu.com/image/pic/item/79f0f736afc3793133040dc5e9c4b74542a911e9.jpg" year:@"1992"], 36 | 37 | [[Album alloc] initWithTitle:@"It's My Life" artist:@"No Doubt" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png" year:@"2003"], 38 | 39 | [[Album alloc] initWithTitle:@"Nothing Like The Sun" artist:@"Sting" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png" year:@"1999"], 40 | 41 | [[Album alloc] initWithTitle:@"Staring at the Sun" artist:@"U2" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_u2_staring%20at%20the%20sun.png" year:@"2000"], 42 | 43 | [[Album alloc] initWithTitle:@"American Pie" artist:@"Madonna" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_madonna_american%20pie.png" year:@"2000"]]]; 44 | 45 | [self saveAlbums]; 46 | } 47 | } 48 | return self; 49 | } 50 | 51 | - (NSArray*)getAlbums 52 | { 53 | return albums; 54 | } 55 | 56 | - (void)addAlbum:(Album*)album atIndex:(NSInteger)index 57 | { 58 | if (albums.count >= index) 59 | [albums insertObject:album atIndex:index]; 60 | else 61 | [albums addObject:album]; 62 | } 63 | 64 | - (void)deleteAlbumAtIndex:(NSInteger)index 65 | { 66 | [albums removeObjectAtIndex:index]; 67 | } 68 | 69 | - (void)saveImage:(UIImage*)image filename:(NSString*)filename 70 | { 71 | filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", filename]; 72 | NSData *data = UIImagePNGRepresentation(image); 73 | [data writeToFile:filename atomically:YES]; 74 | } 75 | 76 | - (UIImage*)getImage:(NSString*)filename 77 | { 78 | filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", filename]; 79 | NSData *data = [NSData dataWithContentsOfFile:filename]; 80 | return [UIImage imageWithData:data]; 81 | } 82 | 83 | - (void)saveAlbums 84 | { 85 | NSString *filename = [NSHomeDirectory() stringByAppendingString:@"/Documents/albums.bin"]; 86 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:albums]; 87 | [data writeToFile:filename atomically:YES]; 88 | } 89 | @end 90 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/xcuserdata/eli.xcuserdatad/xcschemes/BlueLibrary.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/BlueLibrary.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/LibraryAPI.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | class LibraryAPI: NSObject { 26 | private let persistencyManager: PersistencyManager 27 | private let httpClient: HTTPClient 28 | private let isOnline: Bool 29 | 30 | //1 31 | class var sharedInstance: LibraryAPI { 32 | //2 33 | struct Singleton { 34 | //3 35 | static let instance = LibraryAPI() 36 | } 37 | //4 38 | return Singleton.instance 39 | } 40 | 41 | override init() { 42 | persistencyManager = PersistencyManager() 43 | httpClient = HTTPClient() 44 | isOnline = false 45 | 46 | super.init() 47 | 48 | NSNotificationCenter.defaultCenter().addObserver(self, selector:"downloadImage:", name: "BLDownloadImageNotification", object: nil) 49 | } 50 | 51 | deinit { 52 | NSNotificationCenter.defaultCenter().removeObserver(self) 53 | } 54 | 55 | func downloadImage(notification: NSNotification) { 56 | //1 57 | let userInfo = notification.userInfo as [String: AnyObject] 58 | var imageView = userInfo["imageView"] as UIImageView? 59 | let coverUrl = userInfo["coverUrl"] as NSString 60 | 61 | //2 62 | if let imageViewUnWrapped = imageView { 63 | imageViewUnWrapped.image = persistencyManager.getImage(coverUrl.lastPathComponent) 64 | if imageViewUnWrapped.image == nil { 65 | //3 66 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in 67 | let downloadedImage = self.httpClient.downloadImage(coverUrl) 68 | //4 69 | dispatch_sync(dispatch_get_main_queue(), { () -> Void in 70 | imageViewUnWrapped.image = downloadedImage 71 | self.persistencyManager.saveImage(downloadedImage, filename: coverUrl.lastPathComponent) 72 | }) 73 | }) 74 | } 75 | } 76 | } 77 | 78 | func getAlbums() -> [Album] { 79 | return persistencyManager.getAlbums() 80 | } 81 | 82 | func addAlbum(album: Album, index: Int) { 83 | persistencyManager.addAlbum(album, index: index) 84 | if isOnline { 85 | httpClient.postRequest("/api/addAlbum", body: album.description()) 86 | } 87 | } 88 | 89 | func deleteAlbum(index: Int) { 90 | persistencyManager.deleteAlbumAtIndex(index) 91 | if isOnline { 92 | httpClient.postRequest("/api/deleteAlbum", body: "\(index)") 93 | } 94 | } 95 | 96 | func saveAlbums() { 97 | persistencyManager.saveAlbums() 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/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 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/PersistencyManager.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | class PersistencyManager: NSObject { 26 | private var albums : [Album] = [] 27 | 28 | override init() { 29 | super.init() 30 | if let data = NSData(contentsOfFile: NSHomeDirectory().stringByAppendingString("/Documents/albums.bin")) { 31 | let unarchiveAlbums = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [Album]? 32 | if let unwrappedAlbum = unarchiveAlbums { 33 | albums = unwrappedAlbum 34 | } 35 | } else { 36 | createPlaceholderAlbum() 37 | } 38 | } 39 | 40 | func createPlaceholderAlbum() { 41 | //Dummy list of albums 42 | let album1 = Album(title: "Best of Bowie", 43 | artist: "David Bowie", 44 | genre: "Pop", 45 | coverUrl: "http://www.coversproject.com/static/thumbs/album/album_david%20bowie_best%20of%20bowie.png", 46 | year: "1992") 47 | 48 | let album2 = Album(title: "It's My Life", 49 | artist: "No Doubt", 50 | genre: "Pop", 51 | coverUrl: "http://www.coversproject.com/static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png", 52 | year: "2003") 53 | 54 | let album3 = Album(title: "Nothing Like The Sun", 55 | artist: "Sting", 56 | genre: "Pop", 57 | coverUrl: "http://www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png", 58 | year: "1999") 59 | 60 | let album4 = Album(title: "Staring at the Sun", 61 | artist: "U2", 62 | genre: "Pop", 63 | coverUrl: "http://www.coversproject.com/static/thumbs/album/album_u2_staring%20at%20the%20sun.png", 64 | year: "2000") 65 | 66 | let album5 = Album(title: "American Pie", 67 | artist: "Madonna", 68 | genre: "Pop", 69 | coverUrl: "http://www.coversproject.com/static/thumbs/album/album_madonna_american%20pie.png", 70 | year: "2000") 71 | albums = [album1, album2, album3, album4, album5] 72 | saveAlbums() 73 | } 74 | 75 | func getAlbums() -> [Album] { 76 | return albums 77 | } 78 | 79 | func addAlbum(album: Album, index: Int) { 80 | if (albums.count >= index) { 81 | albums.insert(album, atIndex: index) 82 | } else { 83 | albums.append(album) 84 | } 85 | } 86 | 87 | func deleteAlbumAtIndex(index: Int) { 88 | albums.removeAtIndex(index) 89 | } 90 | 91 | func saveImage(image: UIImage, filename: String) { 92 | let path = NSHomeDirectory().stringByAppendingString("/Documents/\(filename)") 93 | let data = UIImagePNGRepresentation(image) 94 | data.writeToFile(path, atomically: true) 95 | } 96 | 97 | func getImage(filename: String) -> UIImage? { 98 | var error: NSError? 99 | let path = NSHomeDirectory().stringByAppendingString("/Documents/\(filename)") 100 | let data = NSData(contentsOfFile: path, options: .UncachedRead, error: &error) 101 | if let unwrappedError = error { 102 | return nil 103 | } else { 104 | return UIImage(data: data!) 105 | } 106 | } 107 | 108 | func saveAlbums() { 109 | var filename = NSHomeDirectory().stringByAppendingString("/Documents/albums.bin") 110 | let data = NSKeyedArchiver.archivedDataWithRootObject(albums) 111 | data.writeToFile(filename, atomically: true) 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary/HorizontalScroller.m: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalScroller.m 3 | // BlueLibrary 4 | // 5 | // Created by skyming on 15/1/30. 6 | // Copyright (c) 2015年 Eli Ganem. All rights reserved. 7 | // 8 | 9 | #import "HorizontalScroller.h" 10 | 11 | 12 | // 1 13 | 14 | #define VIEW_PADDING 10 15 | 16 | #define VIEW_DIMENSIONS 100 17 | 18 | #define VIEWS_OFFSET 100 19 | 20 | // 2 21 | 22 | @interface HorizontalScroller () 23 | 24 | @end 25 | 26 | // 3 27 | @implementation HorizontalScroller 28 | { 29 | 30 | UIScrollView *scroller; 31 | 32 | } 33 | 34 | - (id)initWithFrame:(CGRect)frame 35 | { 36 | self = [super initWithFrame:frame]; 37 | if (self) 38 | { 39 | scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; 40 | scroller.delegate = self; 41 | [self addSubview:scroller]; 42 | 43 | UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollerTapped:)]; 44 | [scroller addGestureRecognizer:tapRecognizer]; 45 | 46 | } 47 | return self; 48 | 49 | } 50 | 51 | - (void)reload 52 | { 53 | 54 | // 1 - nothing to load if there's no delegate 55 | if (self.delegate == nil) return; 56 | 57 | // 2 - remove all subviews 58 | [scroller.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 59 | [obj removeFromSuperview]; 60 | }]; 61 | 62 | // 3 - xValue is the starting point of the views inside the scroller 63 | CGFloat xValue = VIEWS_OFFSET; 64 | for (int i=0; i<[self.delegate numberOfViewsForHorizontalScroller:self]; i++) 65 | { 66 | // 4 - add a view at the right position 67 | xValue += VIEW_PADDING; 68 | UIView *view = [self.delegate horizontalScroller:self viewAtIndex:i]; 69 | view.frame = CGRectMake(xValue, VIEW_PADDING, VIEW_DIMENSIONS, VIEW_DIMENSIONS); 70 | 71 | [scroller addSubview:view]; 72 | xValue += VIEW_DIMENSIONS+VIEW_PADDING; 73 | } 74 | 75 | // 5 76 | [scroller setContentSize:CGSizeMake(xValue+VIEWS_OFFSET, self.frame.size.height)]; 77 | 78 | // 6 - if an initial view is defined, center the scroller on it 79 | if ([self.delegate respondsToSelector:@selector(initialViewIndexForHorizontalScroller:)]) 80 | { 81 | NSInteger initialView = [self.delegate initialViewIndexForHorizontalScroller:self]; 82 | [scroller setContentOffset:CGPointMake(initialView*(VIEW_DIMENSIONS+(2*VIEW_PADDING)), 0) animated:YES]; 83 | } 84 | 85 | } 86 | 87 | - (void)didMoveToSuperview 88 | { 89 | [self reload]; 90 | } 91 | 92 | - (void)centerCurrentView 93 | { 94 | int xFinal = scroller.contentOffset.x + (VIEWS_OFFSET/2) + VIEW_PADDING; 95 | int viewIndex = xFinal / (VIEW_DIMENSIONS+(2*VIEW_PADDING)); 96 | xFinal = viewIndex * (VIEW_DIMENSIONS+(2*VIEW_PADDING)); 97 | // scroller offset 98 | [scroller setContentOffset:CGPointMake(xFinal,0) animated:YES]; 99 | // update Data 100 | [self.delegate horizontalScroller:self clickedViewAtIndex:viewIndex]; 101 | 102 | } 103 | 104 | #pragma mark- ScrollView Delegate 105 | - (void)scrollerTapped:(UITapGestureRecognizer*)gesture 106 | { 107 | CGPoint location = [gesture locationInView:gesture.view]; 108 | 109 | // we can't use an enumerator here, because we don't want to enumerate over ALL of the UIScrollView subviews. 110 | // we want to enumerate only the subviews that we added 111 | 112 | for (int index=0; index<[self.delegate numberOfViewsForHorizontalScroller:self]; index++) 113 | { 114 | UIView *view = scroller.subviews[index]; 115 | if (CGRectContainsPoint(view.frame, location)) 116 | { 117 | [self.delegate horizontalScroller:self clickedViewAtIndex:index]; 118 | CGFloat contentoffsetX = view.frame.origin.x + view.frame.size.width/2 - self.frame.size.width/2; 119 | // NSLog(@"offset: %.2f %.2f",contentoffsetX,self.frame.size.width/2.0); 120 | [scroller setContentOffset:CGPointMake(contentoffsetX, 0) animated:YES]; 121 | break; 122 | } 123 | } 124 | } 125 | 126 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 127 | { 128 | if (!decelerate) 129 | { 130 | [self centerCurrentView]; 131 | } 132 | } 133 | 134 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 135 | { 136 | [self centerCurrentView]; 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/BlueLibrarySwift.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/HorizontalScroller.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | @objc protocol HorizontalScrollerDelegate { 26 | // ask the delegate how many views he wants to present inside the horizontal scroller 27 | func numberOfViewsForHorizontalScroller(scroller: HorizontalScroller) -> Int 28 | // ask the delegate to return the view that should appear at 29 | func horizontalScrollerViewAtIndex(scroller: HorizontalScroller, index:Int) -> UIView 30 | // inform the delegate what the view at has been clicked 31 | func horizontalScrollerClickedViewAtIndex(scroller: HorizontalScroller, index:Int) 32 | // ask the delegate for the index of the initial view to display. this method is optional 33 | // and defaults to 0 if it's not implemented by the delegate 34 | optional func initialViewIndex(scroller: HorizontalScroller) -> Int 35 | } 36 | 37 | class HorizontalScroller: UIView { 38 | weak var delegate: HorizontalScrollerDelegate? 39 | 40 | // 1 41 | private let VIEW_PADDING = 10 42 | private let VIEW_DIMENSIONS = 100 43 | private let VIEWS_OFFSET = 100 44 | 45 | // 2 46 | private var scroller : UIScrollView! 47 | // 3 48 | var viewArray = [UIView]() 49 | 50 | override init(frame: CGRect) { 51 | super.init(frame: frame) 52 | initializeScrollView() 53 | } 54 | 55 | required init(coder aDecoder: NSCoder) { 56 | super.init(coder: aDecoder) 57 | initializeScrollView() 58 | } 59 | 60 | func initializeScrollView() { 61 | //1 62 | scroller = UIScrollView() 63 | addSubview(scroller) 64 | 65 | //2 66 | scroller.setTranslatesAutoresizingMaskIntoConstraints(false) 67 | //3 68 | self.addConstraint(NSLayoutConstraint(item: scroller, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1.0, constant: 0.0)) 69 | self.addConstraint(NSLayoutConstraint(item: scroller, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1.0, constant: 0.0)) 70 | self.addConstraint(NSLayoutConstraint(item: scroller, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1.0, constant: 0.0)) 71 | self.addConstraint(NSLayoutConstraint(item: scroller, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1.0, constant: 0.0)) 72 | 73 | //4 74 | let tapRecognizer = UITapGestureRecognizer(target: self, action:Selector("scrollerTapped:")) 75 | scroller.addGestureRecognizer(tapRecognizer) 76 | } 77 | 78 | func viewAtIndex(index :Int) -> UIView { 79 | return viewArray[index] 80 | } 81 | 82 | func scrollerTapped(gesture: UITapGestureRecognizer) { 83 | let location = gesture.locationInView(gesture.view) 84 | if let delegate = self.delegate { 85 | for index in 0..) -> Void in 110 | object.removeFromSuperview() 111 | } 112 | // 4 - xValue is the starting point of the views inside the scroller 113 | var xValue = VIEWS_OFFSET 114 | for index in 0.. 17 | { 18 | UITableView *dataTable; 19 | NSArray *allAlbums; 20 | NSDictionary *currentAlbumData; 21 | NSInteger currentAlbumIndex; 22 | 23 | HorizontalScroller *scroller; 24 | 25 | UIToolbar *toolbar; 26 | 27 | // We will use this array as a stack to push and pop operation for the undo option 28 | 29 | NSMutableArray *undoStack; 30 | } 31 | @end 32 | 33 | @implementation ViewController 34 | 35 | - (void)viewDidLoad 36 | { 37 | [super viewDidLoad]; 38 | // 1 39 | self.view.backgroundColor = [UIColor colorWithRed:0.76f green:0.81f blue:0.87f alpha:1]; 40 | currentAlbumIndex = 0; 41 | 42 | //2 43 | allAlbums = [[LibraryAPI sharedInstance] getAlbums]; 44 | 45 | // 3 46 | // the uitableview that presents the album data 47 | dataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 120, self.view.frame.size.width, self.view.frame.size.height-120) style:UITableViewStyleGrouped]; 48 | dataTable.delegate = self; 49 | dataTable.dataSource = self; 50 | dataTable.backgroundView = nil; 51 | [self.view addSubview:dataTable]; 52 | 53 | scroller = [[HorizontalScroller alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 120)]; 54 | scroller.backgroundColor = [UIColor colorWithRed:0.24f green:0.35f blue:0.49f alpha:1]; 55 | scroller.delegate = self; 56 | [self.view addSubview:scroller]; 57 | 58 | [self loadPreviousState]; 59 | [self reloadScroller]; 60 | 61 | [self showDataForAlbumAtIndex:currentAlbumIndex]; 62 | 63 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveCurrentState) name:UIApplicationDidEnterBackgroundNotification object:nil]; 64 | 65 | 66 | toolbar = [[UIToolbar alloc] init]; 67 | UIBarButtonItem *undoItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemUndo target:self action:@selector(undoAction)]; 68 | undoItem.enabled = NO; 69 | UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 70 | UIBarButtonItem *delete = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteAlbum)]; 71 | [toolbar setItems:@[undoItem,space,delete]]; 72 | [self.view addSubview:toolbar]; 73 | 74 | undoStack = [[NSMutableArray alloc] init]; 75 | } 76 | 77 | - (void)viewWillLayoutSubviews 78 | { 79 | toolbar.frame = CGRectMake(0, self.view.frame.size.height-44, self.view.frame.size.width, 44); 80 | dataTable.frame = CGRectMake(0, 130, self.view.frame.size.width, self.view.frame.size.height - 200); 81 | } 82 | 83 | - (void)didReceiveMemoryWarning 84 | { 85 | [super didReceiveMemoryWarning]; 86 | // Dispose of any resources that can be recreated. 87 | } 88 | 89 | - (void)dealloc 90 | { 91 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 92 | } 93 | 94 | 95 | 96 | - (void)addAlbum:(Album*)album atIndex:(int)index 97 | { 98 | [[LibraryAPI sharedInstance] addAlbum:album atIndex:index]; 99 | currentAlbumIndex = index; 100 | [self reloadScroller]; 101 | } 102 | 103 | - (void)deleteAlbum 104 | { 105 | // 1 106 | Album *deletedAlbum = allAlbums[currentAlbumIndex]; 107 | 108 | // 2 109 | NSMethodSignature *sig = [self methodSignatureForSelector:@selector(addAlbum:atIndex:)]; 110 | NSInvocation *undoAction = [NSInvocation invocationWithMethodSignature:sig]; 111 | 112 | [undoAction setTarget:self]; 113 | [undoAction setSelector:@selector(addAlbum:atIndex:)]; 114 | [undoAction setArgument:&deletedAlbum atIndex:2]; 115 | [undoAction setArgument:¤tAlbumIndex atIndex:3]; 116 | [undoAction retainArguments]; 117 | 118 | // 3 119 | [undoStack addObject:undoAction]; 120 | 121 | // 4 122 | [[LibraryAPI sharedInstance] deleteAlbumAtIndex:currentAlbumIndex]; 123 | [self reloadScroller]; 124 | 125 | // 5 126 | [toolbar.items[0] setEnabled:YES]; 127 | } 128 | 129 | - (void)undoAction 130 | { 131 | if (undoStack.count > 0) 132 | { 133 | NSInvocation *undoAction = [undoStack lastObject]; 134 | [undoStack removeLastObject]; 135 | [undoAction invoke]; 136 | } 137 | if (undoStack.count == 0) 138 | { 139 | [toolbar.items[0] setEnabled:NO]; 140 | } 141 | } 142 | 143 | - (void)showDataForAlbumAtIndex:(NSInteger )albumIndex 144 | { 145 | // defensive code: make sure the requested index is lower than the amount of albums 146 | if (albumIndex < allAlbums.count) 147 | { 148 | // fetch the album 149 | Album *album = allAlbums[albumIndex]; 150 | // save the albums data to present it later in the tableview 151 | currentAlbumData = [album tr_tableRepresentation]; 152 | } 153 | else 154 | { 155 | currentAlbumData = nil; 156 | } 157 | 158 | // we have the data we need, let's refresh our tableview 159 | [dataTable reloadData]; 160 | } 161 | 162 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 163 | { 164 | return [currentAlbumData[@"titles"] count]; 165 | } 166 | 167 | - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 168 | { 169 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 170 | if (!cell) 171 | { 172 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"]; 173 | } 174 | 175 | cell.textLabel.text = currentAlbumData[@"titles"][indexPath.row]; 176 | cell.detailTextLabel.text = currentAlbumData[@"values"][indexPath.row]; 177 | 178 | return cell; 179 | } 180 | 181 | #pragma mark - HorizontalScrollerDelegate methods 182 | 183 | - (void)horizontalScroller:(HorizontalScroller *)scroller clickedViewAtIndex:(int)index 184 | { 185 | currentAlbumIndex = index; 186 | 187 | [self showDataForAlbumAtIndex:index]; 188 | 189 | } 190 | 191 | - (NSInteger)numberOfViewsForHorizontalScroller:(HorizontalScroller*)scroller 192 | { 193 | return allAlbums.count; 194 | } 195 | 196 | - (UIView*)horizontalScroller:(HorizontalScroller*)scroller viewAtIndex:(int)index 197 | { 198 | Album *album = allAlbums[index]; 199 | return [[AlbumView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) albumCover:album.coverUrl]; 200 | } 201 | 202 | - (void)reloadScroller 203 | { 204 | allAlbums = [[LibraryAPI sharedInstance] getAlbums]; 205 | if (currentAlbumIndex < 0) currentAlbumIndex = 0; 206 | else if (currentAlbumIndex >= allAlbums.count) currentAlbumIndex = allAlbums.count-1; 207 | [scroller reload]; 208 | [self showDataForAlbumAtIndex:currentAlbumIndex]; 209 | } 210 | 211 | - (void)saveCurrentState 212 | { 213 | 214 | // When the user leaves the app and then comes back again, he wants it to be in the exact same state 215 | // he left it. In order to do this we need to save the currently displayed album. 216 | // Since it's only one piece of information we can use NSUserDefaults. 217 | 218 | [[NSUserDefaults standardUserDefaults] setInteger:currentAlbumIndex forKey:@"currentAlbumIndex"]; 219 | [[LibraryAPI sharedInstance] saveAlbums]; 220 | } 221 | 222 | - (void)loadPreviousState 223 | { 224 | currentAlbumIndex = [[NSUserDefaults standardUserDefaults] integerForKey:@"currentAlbumIndex"]; 225 | [self showDataForAlbumAtIndex:currentAlbumIndex]; 226 | } 227 | 228 | 229 | - (NSInteger)initialViewIndexForHorizontalScroller:(HorizontalScroller *)scroller 230 | { 231 | return currentAlbumIndex; 232 | } 233 | @end 234 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/ViewController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Razeware LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | import UIKit 24 | 25 | class ViewController: UIViewController { 26 | 27 | @IBOutlet var dataTable: UITableView! 28 | @IBOutlet var toolbar: UIToolbar! 29 | 30 | @IBOutlet weak var scroller: HorizontalScroller! 31 | 32 | private var allAlbums = [Album]() 33 | private var currentAlbumData : (titles:[String], values:[String])? 34 | private var currentAlbumIndex = 0 35 | 36 | // We will use this array as a stack to push and pop operation for the undo option 37 | var undoStack: [(Album, Int)] = [] 38 | 39 | override func viewDidLoad() { 40 | super.viewDidLoad() 41 | //1 42 | self.navigationController?.navigationBar.translucent = false 43 | currentAlbumIndex = 0 44 | 45 | //2 46 | allAlbums = LibraryAPI.sharedInstance.getAlbums() 47 | 48 | // 3 49 | // the uitableview that presents the album data 50 | dataTable.delegate = self 51 | dataTable.dataSource = self 52 | dataTable.backgroundView = nil 53 | view.addSubview(dataTable!) 54 | 55 | self.showDataForAlbum(currentAlbumIndex) 56 | 57 | loadPreviousState() 58 | 59 | scroller.delegate = self 60 | reloadScroller() 61 | 62 | let undoButton = UIBarButtonItem(barButtonSystemItem: .Undo, target: self, action:"undoAction") 63 | undoButton.enabled = false; 64 | let space = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target:nil, action:nil) 65 | let trashButton = UIBarButtonItem(barButtonSystemItem: .Trash, target:self, action:"deleteAlbum") 66 | let toolbarButtonItems = [undoButton, space, trashButton] 67 | toolbar.setItems(toolbarButtonItems, animated: true) 68 | 69 | NSNotificationCenter.defaultCenter().addObserver(self, selector:"saveCurrentState", name: UIApplicationDidEnterBackgroundNotification, object: nil) 70 | } 71 | 72 | deinit { 73 | NSNotificationCenter.defaultCenter().removeObserver(self) 74 | } 75 | 76 | func initialViewIndex(scroller: HorizontalScroller) -> Int { 77 | return currentAlbumIndex 78 | } 79 | 80 | func showDataForAlbum(albumIndex: Int) { 81 | // defensive code: make sure the requested index is lower than the amount of albums 82 | if (albumIndex < allAlbums.count && albumIndex > -1) { 83 | //fetch the album 84 | let album = allAlbums[albumIndex] 85 | // save the albums data to present it later in the tableview 86 | currentAlbumData = album.ae_tableRepresentation() 87 | } else { 88 | currentAlbumData = nil 89 | } 90 | // we have the data we need, let's refresh our tableview 91 | dataTable!.reloadData() 92 | } 93 | 94 | func reloadScroller() { 95 | allAlbums = LibraryAPI.sharedInstance.getAlbums() 96 | if currentAlbumIndex < 0 { 97 | currentAlbumIndex = 0 98 | } else if currentAlbumIndex >= allAlbums.count { 99 | currentAlbumIndex = allAlbums.count - 1 100 | } 101 | scroller.reload() 102 | showDataForAlbum(currentAlbumIndex) 103 | } 104 | 105 | override func didReceiveMemoryWarning() { 106 | super.didReceiveMemoryWarning() 107 | // Dispose of any resources that can be recreated. 108 | } 109 | 110 | func addAlbumAtIndex(album: Album,index: Int) { 111 | LibraryAPI.sharedInstance.addAlbum(album, index: index) 112 | currentAlbumIndex = index 113 | reloadScroller() 114 | } 115 | 116 | func deleteAlbum() { 117 | //1 118 | var deletedAlbum : Album = allAlbums[currentAlbumIndex] 119 | //2 120 | var undoAction = (deletedAlbum, currentAlbumIndex) 121 | undoStack.insert(undoAction, atIndex: 0) 122 | //3 123 | LibraryAPI.sharedInstance.deleteAlbum(currentAlbumIndex) 124 | reloadScroller() 125 | //4 126 | let barButtonItems = toolbar.items as [UIBarButtonItem] 127 | var undoButton : UIBarButtonItem = barButtonItems[0] 128 | undoButton.enabled = true 129 | //5 130 | if (allAlbums.count == 0) { 131 | var trashButton : UIBarButtonItem = barButtonItems[2] 132 | trashButton.enabled = false 133 | } 134 | } 135 | 136 | func undoAction() { 137 | let barButtonItems = toolbar.items as [UIBarButtonItem] 138 | //1 139 | if undoStack.count > 0 { 140 | let (deletedAlbum, index) = undoStack.removeAtIndex(0) 141 | addAlbumAtIndex(deletedAlbum, index: index) 142 | } 143 | //2 144 | if undoStack.count == 0 { 145 | var undoButton : UIBarButtonItem = barButtonItems[0] 146 | undoButton.enabled = false 147 | } 148 | //3 149 | let trashButton : UIBarButtonItem = barButtonItems[2] 150 | trashButton.enabled = true 151 | } 152 | 153 | //MARK: Memento Pattern 154 | func saveCurrentState() { 155 | // When the user leaves the app and then comes back again, he wants it to be in the exact same state 156 | // he left it. In order to do this we need to save the currently displayed album. 157 | // Since it's only one piece of information we can use NSUserDefaults. 158 | NSUserDefaults.standardUserDefaults().setInteger(currentAlbumIndex, forKey: "currentAlbumIndex") 159 | LibraryAPI.sharedInstance.saveAlbums() 160 | } 161 | 162 | func loadPreviousState() { 163 | currentAlbumIndex = NSUserDefaults.standardUserDefaults().integerForKey("currentAlbumIndex") 164 | showDataForAlbum(currentAlbumIndex) 165 | } 166 | 167 | } 168 | 169 | extension ViewController: UITableViewDataSource { 170 | func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 171 | if let albumData = currentAlbumData { 172 | return albumData.titles.count 173 | } else { 174 | return 0 175 | } 176 | } 177 | 178 | func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 179 | var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell 180 | if let albumData = currentAlbumData { 181 | cell.textLabel?.text = albumData.titles[indexPath.row] 182 | if let detailTextLabel = cell.detailTextLabel { 183 | detailTextLabel.text = albumData.values[indexPath.row] 184 | } 185 | } 186 | return cell 187 | } 188 | } 189 | 190 | extension ViewController: UITableViewDelegate { 191 | } 192 | 193 | extension ViewController: HorizontalScrollerDelegate { 194 | func numberOfViewsForHorizontalScroller(scroller: HorizontalScroller) -> (Int) { 195 | return allAlbums.count 196 | } 197 | 198 | func horizontalScrollerViewAtIndex(scroller: HorizontalScroller, index: Int) -> (UIView) { 199 | let album = allAlbums[index] 200 | let albumView = AlbumView(frame: CGRectMake(0, 0, 100, 100), albumCover: album.coverUrl) 201 | if currentAlbumIndex == index { 202 | albumView.highlightAlbum(didHighlightView: true) 203 | } else { 204 | albumView.highlightAlbum(didHighlightView: false) 205 | } 206 | return albumView 207 | } 208 | 209 | func horizontalScrollerClickedViewAtIndex(scroller: HorizontalScroller, index: Int) { 210 | //1 211 | let previousAlbumView = scroller.viewAtIndex(currentAlbumIndex) as AlbumView 212 | previousAlbumView.highlightAlbum(didHighlightView: false) 213 | //2 214 | currentAlbumIndex = index 215 | //3 216 | let albumView = scroller.viewAtIndex(index) as AlbumView 217 | albumView.highlightAlbum(didHighlightView: true) 218 | //4 219 | showDataForAlbum(index) 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Trip-to-iOS-Design-Patterns 2 | 3 | iOS 设计模式相关资料整理 4 | 随着写代码时间变长,业务逻辑越来越复杂,项目就会变的越来越臃肿,业务的拓展、Bug Fix将会越来越难进展。接着进行的就是重构工作,对重构而已,那设计模式、架构、当前的业务情况、将来可能遇到的需求 将是下一步的思考。本文将从设计模式、架构、实践三个方面梳理 iOS 架构设计。 5 | 6 | #### 必读文章 7 | * [iOS Design Patterns](https://www.raywenderlich.com/46988/ios-design-patterns) 8 | > 文章从 iOS 视角解读了常用的几种设计模式,并给出了代码示例,非常推荐看英文原文,作为设计模式开篇也比较合适,实战性也强。 9 | > 翻译 [一](http://blog.jobbole.com/48115/) [二](http://blog.jobbole.com/48166/) [三](http://blog.jobbole.com/48254/) [四](http://blog.jobbole.com/48179/) 10 | 11 | #### 设计模式 经典图书系列 12 | * 《Head First设计模式》 [纸质版-亚马逊](https://www.amazon.cn/Head-First%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%BC%97%E9%87%8C%E6%9B%BC/dp/B0011FBU34/ref=sr_1_1?ie=UTF8&qid=1464418055&sr=8-1&keywords=head+first) [电子版-PDF-CSDN](http://download.csdn.net/detail/kiratianyi/7471435) 13 | 14 | * 《大话设计模式》[纸质版-亚马逊](https://www.amazon.cn/%E5%A4%A7%E8%AF%9D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E7%A8%8B%E6%9D%B0/dp/B0011FHN5S/ref=sr_1_1?ie=UTF8&qid=1464418409&sr=8-1&keywords=%E5%A4%A7%E8%AF%9D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F)  [源码及电子书-CSDN](http://download.csdn.net/detail/yousuosi/4364766)  [iOS版源码](https://github.com/huang303513/Design-Pattern-For-iOS) 15 | 16 | * 《设计模式》- Gof [纸质版-亚马逊](https://www.amazon.cn/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6%E4%B8%9B%E4%B9%A6-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%8F%AF%E5%A4%8D%E7%94%A8%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BD%AF%E4%BB%B6%E7%9A%84%E5%9F%BA%E7%A1%80-Erich-Gamma/dp/B001130JN8/ref=sr_1_1?ie=UTF8&qid=1464419128&sr=8-1&keywords=%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F) [电子书-PDF-CSDN](http://download.csdn.net/detail/trendgrucee/4795224) 17 | 18 | * 《Objective-C编程之道:iOS 设计模式》 [纸质书-亚马逊](https://www.amazon.cn/Objective-C%E7%BC%96%E7%A8%8B%E4%B9%8B%E9%81%93-iOS%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E8%A7%A3%E6%9E%90-%E9%92%9F%E5%86%A0%E8%B4%A4/dp/B0065V3ALO/ref=sr_1_1?ie=UTF8&qid=1464418960&sr=8-1&keywords=Objective-C%E7%BC%96%E7%A8%8B%E4%B9%8B%E9%81%93%EF%BC%9AiOS+%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F) [电子书及源码](http://download.csdn.net/detail/qiaokeli123456789/6691097) 19 | 20 | #### 设计模式 资源推荐 21 | 22 | * Cocoa Design Patterns  [官方资料](https://developer.apple.com/legacy/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6) [中文翻译版](http://download.csdn.net/detail/sc_cheng/2981710) 23 | 24 | * [史上最全设计模式导学目录(完整版)](http://blog.csdn.net/lovelion/article/details/17517213) 25 | > 强烈推荐,推荐指数五颗星,刘伟老师力作,讲的非常好,通俗易懂,而且举例的应用场景也非常恰当,遗憾的是样例代码是 Java 写的,不过模式是通用的。 26 | 27 | * [图说设计模式](http://design-patterns.readthedocs.org/zh_CN/latest/index.html) 28 | > 推荐指数4颗星,讲了不少UML的相关知识,能更好的理解设计模式中时序图等Mac下的UML工具推荐 StarUML ,做的也不错。 29 | 30 | * [Design-Patterns-In-Swift](https://github.com/ochococo/Design-Patterns-In-Swift) 31 | 32 | #### InfoQ - iOS应用架构谈 - 推荐指数 5星 33 | * [iOS应用架构谈(一):架构设计的方法论](http://casatwy.com/iosying-yong-jia-gou-tan-kai-pian.html) 34 | * [iOS应用架构谈(二):View层的组织和调用方案](http://casatwy.com/iosying-yong-jia-gou-tan-viewceng-de-zu-zhi-he-diao-yong-fang-an.html) 35 | * [iOS应用架构谈(三):网络层设计方案](http://casatwy.com/iosying-yong-jia-gou-tan-wang-luo-ceng-she-ji-fang-an.html) 36 | * [iOS应用架构谈(四):本地持久化方案及动态部署](http://casatwy.com/iosying-yong-jia-gou-tan-ben-di-chi-jiu-hua-fang-an-ji-dong-tai-bu-shu.html) 37 | 38 | #### App 架构设计实践 39 | * [饿了么移动APP的架构演进](https://www.sdk.cn/news/2023) 40 | * [滴滴iOS客户端的架构演变之路](http://www.infoq.com/cn/news/2016/03/lixianhui-interview) 41 | * [携程移动App架构优化之旅](https://mp.weixin.qq.com/s?__biz=MjM5MDE0Mjc4MA==&mid=403412672&idx=1&sn=2cceb873ee4640830aad3261ae177df5&scene=0&key=710a5d99946419d9ba63d1d480eb3f0c2d49be9d244f34e460226b2f4caaa02565fc4d16af8f64ca79085f4db276e89f&ascene=0&uin=MjY1NTg0NzMyMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.11.4+build(15E65)&version=11020201&pass_ticket=JxdNVNrS%2BerOsvJdjWQGHAqgDkV2%2FmL9OHAETsCT%2Bvp0%2B%2FLiXasOwpgYIsgQQn8O)[PPT](http://www.stuq.org/ppt/frame_show/659/4c79d4c7eb2061f8790b5e7e6fe42703#/1) 42 | * [新浪微博iOS客户端架构与优化之路](http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=2651112273&idx=1&sn=893a66a04e541a99b7bc4d7cf227e2f7#rd) 43 | * [Weex详解:移动端高性能动态化方案](http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=2651112231&idx=1&sn=4578ff1009ee774093c45a3d8c19dd58#rd) 44 | * [覃超:Facebook iOS App技术演化十年之路](http://www.infoq.com/cn/articles/evolution-of-facebook-ios-app-ten-years-technology) 45 | * [天弘基金移动App客户端架构优化之路](http://blog.csdn.net/yaoyu/article/details/70184539) 46 | * [Service Oriented 的 iOS 应用架构](http://tech.glowing.com/cn/service-oriented-ios-architecture/) 47 | * [猿题库 iOS 客户端架构设计](http://gracelancy.com/blog/2016/01/06/ape-ios-arch-design/) 48 | * [QCon旧金山演讲总结:阿里无线技术架构演进](http://www.infoq.com/cn/articles/alibaba-mobile-infrastructure) 49 | * [斗米客户端的架构思想](http://blog.linzihong.com/2017/07/27/framework/) 50 | 51 | #### 组件化设计 52 | * [蘑菇街 App 的组件化之路](http://limboy.me/tech/2016/03/10/mgj-components.html) 53 | * [蘑菇街 App 的组件化之路·续](http://limboy.me/tech/2016/03/14/mgj-components-continued.html) 54 | * [iOS应用架构谈(五):组件化方案](http://casatwy.com/iOS-Modulization.html) 55 | * [iOS 组件化方案探索](http://blog.cnbang.net/tech/3080/) 56 | * [糯米移动组件架构演进之路](http://chuansong.me/n/320688951236) 57 | * [滴滴的组件化实践与优化](http://www.infoq.com/cn/articles/xiaojukeji-component-practice-and-optimization) 58 | * [豆瓣App的模块化实践](http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=2651112821&idx=1&sn=2987ba2c9d68e3982e795d9eeb15f82b&chksm=844c6ca8b33be5be42e673ff2a9087628b0d9fab5e5a403d4bd346b134f4ffe110e423967c3e&scene=0#rd) 59 | * [iOS App组件化开发实践](http://www.infoq.com/cn/articles/ios-app-component-development-practice) 60 | * [58 同城 iOS 客户端组件化演变历程](http://mp.weixin.qq.com/s/PbOh-l0E4bD3HoKj0GzYWQ) 61 | * [手机淘宝客户端架构探索实践](https://yq.aliyun.com/articles/129) 62 | * [京东iOS客户端组件管理实践](http://www.infoq.com/cn/articles/jd-ios-component-management?utm_source=articles_about_mobile&utm_medium=link&utm_campaign=mobile) 63 | * [iOS 组件化 —— 路由设计思路分析](https://www.jianshu.com/p/76da56b3bd55) 64 | * [组件化架构漫谈](https://www.jianshu.com/p/67a6004f6930) 65 | 66 | #### IM架构梳理 67 | * [IM 开发者社区](http://www.52im.net/forum.php?mod=collection&op=all) 68 | * [IM架构梳理](http://blog.csdn.net/skymingst/article/details/49448717) 69 | * [58到家消息系统设计与开发实践](https://mp.weixin.qq.com/s?__biz=MzAwNjQwNzU2NQ==&mid=402441278&idx=1&sn=af82781e3e6b694d82ac8454dbe3ae67&scene=0&key=710a5d99946419d9ebeb6a76103f5b3c9a2a96d61dd040e7eaacca508005e842656a35d9b9664ec603be12ce0c3f25c7&ascene=0&uin=MjY1NTg0NzMyMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.11.3+build(15D21)&version=11020201&pass_ticket=TlXzGHRFhCo4eytB1hbIW0fFZq50RM%2BdZKQ7eajgE1C8Lc0aRV7IIgbSt6S4h5eZ) 70 | * [im协议设计选型(上)](https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=205775353&idx=1&sn=ecc1f32ec9585f2c7672a27dfbc726ca&scene=1&srcid=0317WNL1c9K3dhx6rqsrhXL5&key=710a5d99946419d970963f96a056ab527d7e0a5ec70e2094cbb32922797076e77c9282e8ead417792c53ca5798beac51&ascene=0&uin=MjY1NTg0NzMyMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.11.3+build(15D21)&version=11020201&pass_ticket=TlXzGHRFhCo4eytB1hbIW0fFZq50RM%2BdZKQ7eajgE1C8Lc0aRV7IIgbSt6S4h5eZ) 71 | * [webim如何保证消息的可靠投递](https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=205034544&idx=1&sn=26bbbf4a49ae6b6c4b8c3cba7f79764f&scene=1&srcid=0317zhrXNGEHs2T4xAjbCoeO&key=710a5d99946419d9f10782b19962c97c88912b052aadce02ef6e5d82a2b2814aa055d499a22072c468f7c1d3f085cc8a&ascene=0&uin=MjY1NTg0NzMyMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.11.3+build(15D21)&version=11020201&pass_ticket=TlXzGHRFhCo4eytB1hbIW0fFZq50RM%2BdZKQ7eajgE1C8Lc0aRV7IIgbSt6S4h5eZ) 72 | * [webim如何用轮询保证消息绝对实时](https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=205001346&idx=1&sn=fd87cc010bf4548589c9fabea80c4cad&scene=1&srcid=0317oohatukhxTbBwWHKP6cU&key=710a5d99946419d9708e602d966c3a50e34f09ca848c5b3bf380b79bc6b34ad6e84062ed43a22333531a6525cc8fa07d&ascene=0&uin=MjY1NTg0NzMyMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.11.3+build(15D21)&version=11020201&pass_ticket=TlXzGHRFhCo4eytB1hbIW0fFZq50RM%2BdZKQ7eajgE1C8Lc0aRV7IIgbSt6S4h5eZ) 73 | * [一套简洁的即时通信 (IM) 系统](https://mp.weixin.qq.com/s?__biz=MjM5MzA0ODkyMA==&mid=405991976&idx=1&sn=4bf8982f2dc2ea2df62c312e4fe508f4&scene=0&key=710a5d99946419d98e3fd2dc46318f0db3ec6994c949bcf1ed7aa9792993c67eb1388d95f0019d30c30a407b14211064&ascene=0&uin=MjY1NTg0NzMyMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.11.3+build(15D21)&version=11020201&pass_ticket=TlXzGHRFhCo4eytB1hbIW0fFZq50RM%2BdZKQ7eajgE1C8Lc0aRV7IIgbSt6S4h5eZ) 74 | * [微博与im消息实现对比[随想]](https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=205117508&idx=1&sn=71eecf04581e68deee4a44f7786309f5&scene=1&srcid=0317jpSQhhxbYvM2Kz6vlhOK&key=710a5d99946419d9c798c52d8b5dd4f67c1c4b144bb07217906e72260d353ac92559a0451d7548f74cc70ca9e0223637&ascene=0&uin=MjY1NTg0NzMyMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.11.3+build(15D21)&version=11020201&pass_ticket=TlXzGHRFhCo4eytB1hbIW0fFZq50RM%2BdZKQ7eajgE1C8Lc0aRV7IIgbSt6S4h5eZ) 75 | 76 | 77 | #### 实战学习 78 | 最后推荐些可以帮助理解实战的开源项目: 79 | 80 | * [V2EX - V2EX iOS客户端,已上线项目](https://github.com/singro/v2ex) 81 | * [Firox-IOS - Firox iOS客户端,用Swift写的](https://github.com/mozilla/firefox-ios) 82 | * [Telegram - 一个非常牛XXX的开源社交项目](https://github.com/peter-iakovlev/Telegram) 83 | * [网易云信开源UI组件](https://github.com/netease-im/NIM_iOS_Demo) 84 | 85 | 86 | #### 其他资源: 87 | 88 | * [objccn - 架构 - 强烈推荐](http://objccn.io/issue-13/) 89 | * [怎么面试架构师](http://www.cocoachina.com/programmer/20150617/12170.html) 90 | * [EasyIOS](https://github.com/zhuchaowe/EasyIOS) 91 | * [移动App架构设计](https://github.com/uxyheaven/NativeAppFrameworkDesign) 92 | * [探索 Swift 中的 MVC-N 模式](https://realm.io/cn/news/slug-marcus-zarra-exploring-mvcn-swift/?utm_source=tuicool&utm_medium=referral) 93 | * [MVVMFramework](https://github.com/lovemo/MVVMFramework) 94 | * [iOS设计模式之观察者模式](http://blog.jobbole.com/55505/) 95 | * [iOS设计模式反思之单例模式的进化-非翻译](http://blog.jobbole.com/56439/) 96 | * [关于 23 种设计模式的有趣见解-非翻译](http://blog.jobbole.com/20496/) 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift/Base.lproj/Main.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 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Objc/BlueLibrary.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 450EECC017A9B03A00957F62 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 450EECBF17A9B03A00957F62 /* UIKit.framework */; }; 11 | 450EECC217A9B03A00957F62 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 450EECC117A9B03A00957F62 /* Foundation.framework */; }; 12 | 450EECC417A9B03A00957F62 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 450EECC317A9B03A00957F62 /* CoreGraphics.framework */; }; 13 | 450EECCA17A9B03A00957F62 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 450EECC817A9B03A00957F62 /* InfoPlist.strings */; }; 14 | 450EECCC17A9B03A00957F62 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 450EECCB17A9B03A00957F62 /* main.m */; }; 15 | 450EECD017A9B03A00957F62 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 450EECCF17A9B03A00957F62 /* AppDelegate.m */; }; 16 | 450EECD217A9B03A00957F62 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 450EECD117A9B03A00957F62 /* Default.png */; }; 17 | 450EECD417A9B03A00957F62 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 450EECD317A9B03A00957F62 /* Default@2x.png */; }; 18 | 450EECD617A9B03A00957F62 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 450EECD517A9B03A00957F62 /* Default-568h@2x.png */; }; 19 | 450EECD917A9B03A00957F62 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 450EECD817A9B03A00957F62 /* ViewController.m */; }; 20 | 450EECE517A9B05E00957F62 /* HTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 450EECE417A9B05E00957F62 /* HTTPClient.m */; }; 21 | 84DA77D81A7B950F002CD304 /* Album.m in Sources */ = {isa = PBXBuildFile; fileRef = 84DA77D71A7B950F002CD304 /* Album.m */; }; 22 | 84DA77DB1A7B96C9002CD304 /* AlbumView.m in Sources */ = {isa = PBXBuildFile; fileRef = 84DA77DA1A7B96C9002CD304 /* AlbumView.m */; }; 23 | 84DA77E21A7B99F7002CD304 /* LibraryAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 84DA77E11A7B99F7002CD304 /* LibraryAPI.m */; }; 24 | 84DA77E61A7B9A8A002CD304 /* PersistencyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 84DA77E51A7B9A8A002CD304 /* PersistencyManager.m */; }; 25 | 84DA77E91A7BA8D3002CD304 /* Album+TableRepresentation.m in Sources */ = {isa = PBXBuildFile; fileRef = 84DA77E81A7BA8D3002CD304 /* Album+TableRepresentation.m */; }; 26 | 84DA77EC1A7BA9EC002CD304 /* HorizontalScroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 84DA77EB1A7BA9EC002CD304 /* HorizontalScroller.m */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 450EECBC17A9B03A00957F62 /* BlueLibrary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BlueLibrary.app; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 450EECBF17A9B03A00957F62 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 32 | 450EECC117A9B03A00957F62 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 33 | 450EECC317A9B03A00957F62 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 34 | 450EECC717A9B03A00957F62 /* BlueLibrary-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "BlueLibrary-Info.plist"; sourceTree = ""; }; 35 | 450EECC917A9B03A00957F62 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 36 | 450EECCB17A9B03A00957F62 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 37 | 450EECCD17A9B03A00957F62 /* BlueLibrary-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BlueLibrary-Prefix.pch"; sourceTree = ""; }; 38 | 450EECCE17A9B03A00957F62 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 39 | 450EECCF17A9B03A00957F62 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 40 | 450EECD117A9B03A00957F62 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 41 | 450EECD317A9B03A00957F62 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 42 | 450EECD517A9B03A00957F62 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 43 | 450EECD717A9B03A00957F62 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 44 | 450EECD817A9B03A00957F62 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 45 | 450EECE317A9B05E00957F62 /* HTTPClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPClient.h; sourceTree = ""; }; 46 | 450EECE417A9B05E00957F62 /* HTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTTPClient.m; sourceTree = ""; }; 47 | 84DA77D61A7B950F002CD304 /* Album.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Album.h; sourceTree = ""; }; 48 | 84DA77D71A7B950F002CD304 /* Album.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Album.m; sourceTree = ""; }; 49 | 84DA77D91A7B96C9002CD304 /* AlbumView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumView.h; sourceTree = ""; }; 50 | 84DA77DA1A7B96C9002CD304 /* AlbumView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumView.m; sourceTree = ""; }; 51 | 84DA77E01A7B99F7002CD304 /* LibraryAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LibraryAPI.h; sourceTree = ""; }; 52 | 84DA77E11A7B99F7002CD304 /* LibraryAPI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LibraryAPI.m; sourceTree = ""; }; 53 | 84DA77E41A7B9A8A002CD304 /* PersistencyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PersistencyManager.h; sourceTree = ""; }; 54 | 84DA77E51A7B9A8A002CD304 /* PersistencyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PersistencyManager.m; sourceTree = ""; }; 55 | 84DA77E71A7BA8D3002CD304 /* Album+TableRepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Album+TableRepresentation.h"; sourceTree = ""; }; 56 | 84DA77E81A7BA8D3002CD304 /* Album+TableRepresentation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Album+TableRepresentation.m"; sourceTree = ""; }; 57 | 84DA77EA1A7BA9EC002CD304 /* HorizontalScroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HorizontalScroller.h; sourceTree = ""; }; 58 | 84DA77EB1A7BA9EC002CD304 /* HorizontalScroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HorizontalScroller.m; sourceTree = ""; }; 59 | /* End PBXFileReference section */ 60 | 61 | /* Begin PBXFrameworksBuildPhase section */ 62 | 450EECB917A9B03A00957F62 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | 450EECC017A9B03A00957F62 /* UIKit.framework in Frameworks */, 67 | 450EECC217A9B03A00957F62 /* Foundation.framework in Frameworks */, 68 | 450EECC417A9B03A00957F62 /* CoreGraphics.framework in Frameworks */, 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXFrameworksBuildPhase section */ 73 | 74 | /* Begin PBXGroup section */ 75 | 450EECB317A9B03A00957F62 = { 76 | isa = PBXGroup; 77 | children = ( 78 | 450EECC517A9B03A00957F62 /* BlueLibrary */, 79 | 450EECBE17A9B03A00957F62 /* Frameworks */, 80 | 450EECBD17A9B03A00957F62 /* Products */, 81 | ); 82 | sourceTree = ""; 83 | }; 84 | 450EECBD17A9B03A00957F62 /* Products */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 450EECBC17A9B03A00957F62 /* BlueLibrary.app */, 88 | ); 89 | name = Products; 90 | sourceTree = ""; 91 | }; 92 | 450EECBE17A9B03A00957F62 /* Frameworks */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 450EECBF17A9B03A00957F62 /* UIKit.framework */, 96 | 450EECC117A9B03A00957F62 /* Foundation.framework */, 97 | 450EECC317A9B03A00957F62 /* CoreGraphics.framework */, 98 | ); 99 | name = Frameworks; 100 | sourceTree = ""; 101 | }; 102 | 450EECC517A9B03A00957F62 /* BlueLibrary */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 450EECE217A9B04400957F62 /* API */, 106 | 84DA77DC1A7B9797002CD304 /* Controller */, 107 | 84DA77DD1A7B97A5002CD304 /* Model */, 108 | 84DA77DE1A7B97AE002CD304 /* View */, 109 | 84DA77E31A7B99FF002CD304 /* Util */, 110 | 450EECCE17A9B03A00957F62 /* AppDelegate.h */, 111 | 450EECCF17A9B03A00957F62 /* AppDelegate.m */, 112 | 450EECC617A9B03A00957F62 /* Supporting Files */, 113 | ); 114 | path = BlueLibrary; 115 | sourceTree = ""; 116 | }; 117 | 450EECC617A9B03A00957F62 /* Supporting Files */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 450EECC717A9B03A00957F62 /* BlueLibrary-Info.plist */, 121 | 450EECC817A9B03A00957F62 /* InfoPlist.strings */, 122 | 450EECCB17A9B03A00957F62 /* main.m */, 123 | 450EECCD17A9B03A00957F62 /* BlueLibrary-Prefix.pch */, 124 | 450EECD117A9B03A00957F62 /* Default.png */, 125 | 450EECD317A9B03A00957F62 /* Default@2x.png */, 126 | 450EECD517A9B03A00957F62 /* Default-568h@2x.png */, 127 | ); 128 | name = "Supporting Files"; 129 | sourceTree = ""; 130 | }; 131 | 450EECE217A9B04400957F62 /* API */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 84DA77E01A7B99F7002CD304 /* LibraryAPI.h */, 135 | 84DA77E11A7B99F7002CD304 /* LibraryAPI.m */, 136 | 84DA77E41A7B9A8A002CD304 /* PersistencyManager.h */, 137 | 84DA77E51A7B9A8A002CD304 /* PersistencyManager.m */, 138 | 450EECE317A9B05E00957F62 /* HTTPClient.h */, 139 | 450EECE417A9B05E00957F62 /* HTTPClient.m */, 140 | ); 141 | name = API; 142 | sourceTree = ""; 143 | }; 144 | 84DA77DC1A7B9797002CD304 /* Controller */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 450EECD717A9B03A00957F62 /* ViewController.h */, 148 | 450EECD817A9B03A00957F62 /* ViewController.m */, 149 | ); 150 | name = Controller; 151 | sourceTree = ""; 152 | }; 153 | 84DA77DD1A7B97A5002CD304 /* Model */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 84DA77D61A7B950F002CD304 /* Album.h */, 157 | 84DA77D71A7B950F002CD304 /* Album.m */, 158 | ); 159 | name = Model; 160 | sourceTree = ""; 161 | }; 162 | 84DA77DE1A7B97AE002CD304 /* View */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 84DA77D91A7B96C9002CD304 /* AlbumView.h */, 166 | 84DA77DA1A7B96C9002CD304 /* AlbumView.m */, 167 | 84DA77EA1A7BA9EC002CD304 /* HorizontalScroller.h */, 168 | 84DA77EB1A7BA9EC002CD304 /* HorizontalScroller.m */, 169 | ); 170 | name = View; 171 | sourceTree = ""; 172 | }; 173 | 84DA77E31A7B99FF002CD304 /* Util */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 84DA77E71A7BA8D3002CD304 /* Album+TableRepresentation.h */, 177 | 84DA77E81A7BA8D3002CD304 /* Album+TableRepresentation.m */, 178 | ); 179 | name = Util; 180 | sourceTree = ""; 181 | }; 182 | /* End PBXGroup section */ 183 | 184 | /* Begin PBXNativeTarget section */ 185 | 450EECBB17A9B03A00957F62 /* BlueLibrary */ = { 186 | isa = PBXNativeTarget; 187 | buildConfigurationList = 450EECDF17A9B03A00957F62 /* Build configuration list for PBXNativeTarget "BlueLibrary" */; 188 | buildPhases = ( 189 | 450EECB817A9B03A00957F62 /* Sources */, 190 | 450EECB917A9B03A00957F62 /* Frameworks */, 191 | 450EECBA17A9B03A00957F62 /* Resources */, 192 | ); 193 | buildRules = ( 194 | ); 195 | dependencies = ( 196 | ); 197 | name = BlueLibrary; 198 | productName = BlueLibrary; 199 | productReference = 450EECBC17A9B03A00957F62 /* BlueLibrary.app */; 200 | productType = "com.apple.product-type.application"; 201 | }; 202 | /* End PBXNativeTarget section */ 203 | 204 | /* Begin PBXProject section */ 205 | 450EECB417A9B03A00957F62 /* Project object */ = { 206 | isa = PBXProject; 207 | attributes = { 208 | LastUpgradeCheck = 0460; 209 | ORGANIZATIONNAME = "Eli Ganem"; 210 | }; 211 | buildConfigurationList = 450EECB717A9B03A00957F62 /* Build configuration list for PBXProject "BlueLibrary" */; 212 | compatibilityVersion = "Xcode 3.2"; 213 | developmentRegion = English; 214 | hasScannedForEncodings = 0; 215 | knownRegions = ( 216 | en, 217 | ); 218 | mainGroup = 450EECB317A9B03A00957F62; 219 | productRefGroup = 450EECBD17A9B03A00957F62 /* Products */; 220 | projectDirPath = ""; 221 | projectRoot = ""; 222 | targets = ( 223 | 450EECBB17A9B03A00957F62 /* BlueLibrary */, 224 | ); 225 | }; 226 | /* End PBXProject section */ 227 | 228 | /* Begin PBXResourcesBuildPhase section */ 229 | 450EECBA17A9B03A00957F62 /* Resources */ = { 230 | isa = PBXResourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | 450EECCA17A9B03A00957F62 /* InfoPlist.strings in Resources */, 234 | 450EECD217A9B03A00957F62 /* Default.png in Resources */, 235 | 450EECD417A9B03A00957F62 /* Default@2x.png in Resources */, 236 | 450EECD617A9B03A00957F62 /* Default-568h@2x.png in Resources */, 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | }; 240 | /* End PBXResourcesBuildPhase section */ 241 | 242 | /* Begin PBXSourcesBuildPhase section */ 243 | 450EECB817A9B03A00957F62 /* Sources */ = { 244 | isa = PBXSourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 450EECCC17A9B03A00957F62 /* main.m in Sources */, 248 | 450EECD017A9B03A00957F62 /* AppDelegate.m in Sources */, 249 | 84DA77DB1A7B96C9002CD304 /* AlbumView.m in Sources */, 250 | 84DA77E61A7B9A8A002CD304 /* PersistencyManager.m in Sources */, 251 | 84DA77E21A7B99F7002CD304 /* LibraryAPI.m in Sources */, 252 | 84DA77EC1A7BA9EC002CD304 /* HorizontalScroller.m in Sources */, 253 | 450EECD917A9B03A00957F62 /* ViewController.m in Sources */, 254 | 84DA77E91A7BA8D3002CD304 /* Album+TableRepresentation.m in Sources */, 255 | 84DA77D81A7B950F002CD304 /* Album.m in Sources */, 256 | 450EECE517A9B05E00957F62 /* HTTPClient.m in Sources */, 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | /* End PBXSourcesBuildPhase section */ 261 | 262 | /* Begin PBXVariantGroup section */ 263 | 450EECC817A9B03A00957F62 /* InfoPlist.strings */ = { 264 | isa = PBXVariantGroup; 265 | children = ( 266 | 450EECC917A9B03A00957F62 /* en */, 267 | ); 268 | name = InfoPlist.strings; 269 | sourceTree = ""; 270 | }; 271 | /* End PBXVariantGroup section */ 272 | 273 | /* Begin XCBuildConfiguration section */ 274 | 450EECDD17A9B03A00957F62 /* Debug */ = { 275 | isa = XCBuildConfiguration; 276 | buildSettings = { 277 | ALWAYS_SEARCH_USER_PATHS = NO; 278 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 279 | CLANG_CXX_LIBRARY = "libc++"; 280 | CLANG_ENABLE_OBJC_ARC = YES; 281 | CLANG_WARN_CONSTANT_CONVERSION = YES; 282 | CLANG_WARN_EMPTY_BODY = YES; 283 | CLANG_WARN_ENUM_CONVERSION = YES; 284 | CLANG_WARN_INT_CONVERSION = YES; 285 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 286 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 287 | COPY_PHASE_STRIP = NO; 288 | GCC_C_LANGUAGE_STANDARD = gnu99; 289 | GCC_DYNAMIC_NO_PIC = NO; 290 | GCC_OPTIMIZATION_LEVEL = 0; 291 | GCC_PREPROCESSOR_DEFINITIONS = ( 292 | "DEBUG=1", 293 | "$(inherited)", 294 | ); 295 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 296 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 297 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 298 | GCC_WARN_UNUSED_VARIABLE = YES; 299 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 300 | ONLY_ACTIVE_ARCH = YES; 301 | SDKROOT = iphoneos; 302 | }; 303 | name = Debug; 304 | }; 305 | 450EECDE17A9B03A00957F62 /* Release */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 310 | CLANG_CXX_LIBRARY = "libc++"; 311 | CLANG_ENABLE_OBJC_ARC = YES; 312 | CLANG_WARN_CONSTANT_CONVERSION = YES; 313 | CLANG_WARN_EMPTY_BODY = YES; 314 | CLANG_WARN_ENUM_CONVERSION = YES; 315 | CLANG_WARN_INT_CONVERSION = YES; 316 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 317 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 318 | COPY_PHASE_STRIP = YES; 319 | GCC_C_LANGUAGE_STANDARD = gnu99; 320 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 321 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 324 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 325 | SDKROOT = iphoneos; 326 | VALIDATE_PRODUCT = YES; 327 | }; 328 | name = Release; 329 | }; 330 | 450EECE017A9B03A00957F62 /* Debug */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 334 | GCC_PREFIX_HEADER = "BlueLibrary/BlueLibrary-Prefix.pch"; 335 | INFOPLIST_FILE = "BlueLibrary/BlueLibrary-Info.plist"; 336 | PRODUCT_NAME = "$(TARGET_NAME)"; 337 | WRAPPER_EXTENSION = app; 338 | }; 339 | name = Debug; 340 | }; 341 | 450EECE117A9B03A00957F62 /* Release */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 345 | GCC_PREFIX_HEADER = "BlueLibrary/BlueLibrary-Prefix.pch"; 346 | INFOPLIST_FILE = "BlueLibrary/BlueLibrary-Info.plist"; 347 | PRODUCT_NAME = "$(TARGET_NAME)"; 348 | WRAPPER_EXTENSION = app; 349 | }; 350 | name = Release; 351 | }; 352 | /* End XCBuildConfiguration section */ 353 | 354 | /* Begin XCConfigurationList section */ 355 | 450EECB717A9B03A00957F62 /* Build configuration list for PBXProject "BlueLibrary" */ = { 356 | isa = XCConfigurationList; 357 | buildConfigurations = ( 358 | 450EECDD17A9B03A00957F62 /* Debug */, 359 | 450EECDE17A9B03A00957F62 /* Release */, 360 | ); 361 | defaultConfigurationIsVisible = 0; 362 | defaultConfigurationName = Release; 363 | }; 364 | 450EECDF17A9B03A00957F62 /* Build configuration list for PBXNativeTarget "BlueLibrary" */ = { 365 | isa = XCConfigurationList; 366 | buildConfigurations = ( 367 | 450EECE017A9B03A00957F62 /* Debug */, 368 | 450EECE117A9B03A00957F62 /* Release */, 369 | ); 370 | defaultConfigurationIsVisible = 0; 371 | defaultConfigurationName = Release; 372 | }; 373 | /* End XCConfigurationList section */ 374 | }; 375 | rootObject = 450EECB417A9B03A00957F62 /* Project object */; 376 | } 377 | -------------------------------------------------------------------------------- /SimpleCode/BlueLibrary-Swift/BlueLibrarySwift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 101DD6CB1A052EDE00161F0D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101DD6CA1A052EDE00161F0D /* AppDelegate.swift */; }; 11 | 101DD6CD1A052EDE00161F0D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101DD6CC1A052EDE00161F0D /* ViewController.swift */; }; 12 | 101DD6D01A052EDE00161F0D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 101DD6CE1A052EDE00161F0D /* Main.storyboard */; }; 13 | 101DD6D21A052EDE00161F0D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 101DD6D11A052EDE00161F0D /* Images.xcassets */; }; 14 | 101DD6D51A052EDE00161F0D /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 101DD6D31A052EDE00161F0D /* LaunchScreen.xib */; }; 15 | 101DD6E11A052EDE00161F0D /* BlueLibrarySwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101DD6E01A052EDE00161F0D /* BlueLibrarySwiftTests.swift */; }; 16 | 101DD6EC1A052F0E00161F0D /* HTTPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 101DD6EB1A052F0E00161F0D /* HTTPClient.swift */; }; 17 | 785E1AA11A34F5D500C42E3B /* HorizontalScroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 785E1AA01A34F5D500C42E3B /* HorizontalScroller.swift */; }; 18 | 78C69A151A33AF6200B923C8 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C69A141A33AF6200B923C8 /* Album.swift */; }; 19 | 78C69A171A33B00B00B923C8 /* AlbumView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C69A161A33B00B00B923C8 /* AlbumView.swift */; }; 20 | 78C69A191A33BD0B00B923C8 /* LibraryAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C69A181A33BD0B00B923C8 /* LibraryAPI.swift */; }; 21 | 78C69A1B1A33C9EF00B923C8 /* PersistencyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C69A1A1A33C9EF00B923C8 /* PersistencyManager.swift */; }; 22 | 78C69A1D1A34C56F00B923C8 /* AlbumExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C69A1C1A34C56F00B923C8 /* AlbumExtensions.swift */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 101DD6DB1A052EDE00161F0D /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 101DD6BD1A052EDE00161F0D /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 101DD6C41A052EDE00161F0D; 31 | remoteInfo = BlueLibrarySwift; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 101DD6C51A052EDE00161F0D /* BlueLibrarySwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BlueLibrarySwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 101DD6C91A052EDE00161F0D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 38 | 101DD6CA1A052EDE00161F0D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 39 | 101DD6CC1A052EDE00161F0D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 40 | 101DD6CF1A052EDE00161F0D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 41 | 101DD6D11A052EDE00161F0D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 42 | 101DD6D41A052EDE00161F0D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 43 | 101DD6DA1A052EDE00161F0D /* BlueLibrarySwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BlueLibrarySwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 101DD6DF1A052EDE00161F0D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | 101DD6E01A052EDE00161F0D /* BlueLibrarySwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlueLibrarySwiftTests.swift; sourceTree = ""; }; 46 | 101DD6EB1A052F0E00161F0D /* HTTPClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPClient.swift; sourceTree = ""; }; 47 | 785E1AA01A34F5D500C42E3B /* HorizontalScroller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HorizontalScroller.swift; sourceTree = ""; }; 48 | 78C69A141A33AF6200B923C8 /* Album.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = ""; }; 49 | 78C69A161A33B00B00B923C8 /* AlbumView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumView.swift; sourceTree = ""; }; 50 | 78C69A181A33BD0B00B923C8 /* LibraryAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryAPI.swift; sourceTree = ""; }; 51 | 78C69A1A1A33C9EF00B923C8 /* PersistencyManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersistencyManager.swift; sourceTree = ""; }; 52 | 78C69A1C1A34C56F00B923C8 /* AlbumExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumExtensions.swift; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 101DD6C21A052EDE00161F0D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | 101DD6D71A052EDE00161F0D /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | 101DD6BC1A052EDE00161F0D = { 74 | isa = PBXGroup; 75 | children = ( 76 | 101DD6C71A052EDE00161F0D /* BlueLibrarySwift */, 77 | 101DD6DD1A052EDE00161F0D /* BlueLibrarySwiftTests */, 78 | 101DD6C61A052EDE00161F0D /* Products */, 79 | ); 80 | sourceTree = ""; 81 | }; 82 | 101DD6C61A052EDE00161F0D /* Products */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 101DD6C51A052EDE00161F0D /* BlueLibrarySwift.app */, 86 | 101DD6DA1A052EDE00161F0D /* BlueLibrarySwiftTests.xctest */, 87 | ); 88 | name = Products; 89 | sourceTree = ""; 90 | }; 91 | 101DD6C71A052EDE00161F0D /* BlueLibrarySwift */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 101DD6EA1A052EE400161F0D /* API */, 95 | 784B4B6E1A34F59700B6DB9F /* Controller */, 96 | 784B4B6C1A34F58A00B6DB9F /* Model */, 97 | 784B4B6D1A34F59200B6DB9F /* View */, 98 | 101DD6CE1A052EDE00161F0D /* Main.storyboard */, 99 | 101DD6D11A052EDE00161F0D /* Images.xcassets */, 100 | 101DD6D31A052EDE00161F0D /* LaunchScreen.xib */, 101 | 101DD6CA1A052EDE00161F0D /* AppDelegate.swift */, 102 | 101DD6C81A052EDE00161F0D /* Supporting Files */, 103 | ); 104 | path = BlueLibrarySwift; 105 | sourceTree = ""; 106 | }; 107 | 101DD6C81A052EDE00161F0D /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 101DD6C91A052EDE00161F0D /* Info.plist */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | 101DD6DD1A052EDE00161F0D /* BlueLibrarySwiftTests */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 101DD6E01A052EDE00161F0D /* BlueLibrarySwiftTests.swift */, 119 | 101DD6DE1A052EDE00161F0D /* Supporting Files */, 120 | ); 121 | path = BlueLibrarySwiftTests; 122 | sourceTree = ""; 123 | }; 124 | 101DD6DE1A052EDE00161F0D /* Supporting Files */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 101DD6DF1A052EDE00161F0D /* Info.plist */, 128 | ); 129 | name = "Supporting Files"; 130 | sourceTree = ""; 131 | }; 132 | 101DD6EA1A052EE400161F0D /* API */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 101DD6EB1A052F0E00161F0D /* HTTPClient.swift */, 136 | 78C69A181A33BD0B00B923C8 /* LibraryAPI.swift */, 137 | 78C69A1A1A33C9EF00B923C8 /* PersistencyManager.swift */, 138 | ); 139 | name = API; 140 | sourceTree = ""; 141 | }; 142 | 784B4B6C1A34F58A00B6DB9F /* Model */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 78C69A141A33AF6200B923C8 /* Album.swift */, 146 | 78C69A1C1A34C56F00B923C8 /* AlbumExtensions.swift */, 147 | ); 148 | name = Model; 149 | sourceTree = ""; 150 | }; 151 | 784B4B6D1A34F59200B6DB9F /* View */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 78C69A161A33B00B00B923C8 /* AlbumView.swift */, 155 | 785E1AA01A34F5D500C42E3B /* HorizontalScroller.swift */, 156 | ); 157 | name = View; 158 | sourceTree = ""; 159 | }; 160 | 784B4B6E1A34F59700B6DB9F /* Controller */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 101DD6CC1A052EDE00161F0D /* ViewController.swift */, 164 | ); 165 | name = Controller; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 101DD6C41A052EDE00161F0D /* BlueLibrarySwift */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 101DD6E41A052EDE00161F0D /* Build configuration list for PBXNativeTarget "BlueLibrarySwift" */; 174 | buildPhases = ( 175 | 101DD6C11A052EDE00161F0D /* Sources */, 176 | 101DD6C21A052EDE00161F0D /* Frameworks */, 177 | 101DD6C31A052EDE00161F0D /* Resources */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | ); 183 | name = BlueLibrarySwift; 184 | productName = BlueLibrarySwift; 185 | productReference = 101DD6C51A052EDE00161F0D /* BlueLibrarySwift.app */; 186 | productType = "com.apple.product-type.application"; 187 | }; 188 | 101DD6D91A052EDE00161F0D /* BlueLibrarySwiftTests */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = 101DD6E71A052EDE00161F0D /* Build configuration list for PBXNativeTarget "BlueLibrarySwiftTests" */; 191 | buildPhases = ( 192 | 101DD6D61A052EDE00161F0D /* Sources */, 193 | 101DD6D71A052EDE00161F0D /* Frameworks */, 194 | 101DD6D81A052EDE00161F0D /* Resources */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | 101DD6DC1A052EDE00161F0D /* PBXTargetDependency */, 200 | ); 201 | name = BlueLibrarySwiftTests; 202 | productName = BlueLibrarySwiftTests; 203 | productReference = 101DD6DA1A052EDE00161F0D /* BlueLibrarySwiftTests.xctest */; 204 | productType = "com.apple.product-type.bundle.unit-test"; 205 | }; 206 | /* End PBXNativeTarget section */ 207 | 208 | /* Begin PBXProject section */ 209 | 101DD6BD1A052EDE00161F0D /* Project object */ = { 210 | isa = PBXProject; 211 | attributes = { 212 | LastUpgradeCheck = 0610; 213 | ORGANIZATIONNAME = Raywenderlich; 214 | TargetAttributes = { 215 | 101DD6C41A052EDE00161F0D = { 216 | CreatedOnToolsVersion = 6.1; 217 | }; 218 | 101DD6D91A052EDE00161F0D = { 219 | CreatedOnToolsVersion = 6.1; 220 | TestTargetID = 101DD6C41A052EDE00161F0D; 221 | }; 222 | }; 223 | }; 224 | buildConfigurationList = 101DD6C01A052EDE00161F0D /* Build configuration list for PBXProject "BlueLibrarySwift" */; 225 | compatibilityVersion = "Xcode 3.2"; 226 | developmentRegion = English; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | Base, 231 | ); 232 | mainGroup = 101DD6BC1A052EDE00161F0D; 233 | productRefGroup = 101DD6C61A052EDE00161F0D /* Products */; 234 | projectDirPath = ""; 235 | projectRoot = ""; 236 | targets = ( 237 | 101DD6C41A052EDE00161F0D /* BlueLibrarySwift */, 238 | 101DD6D91A052EDE00161F0D /* BlueLibrarySwiftTests */, 239 | ); 240 | }; 241 | /* End PBXProject section */ 242 | 243 | /* Begin PBXResourcesBuildPhase section */ 244 | 101DD6C31A052EDE00161F0D /* Resources */ = { 245 | isa = PBXResourcesBuildPhase; 246 | buildActionMask = 2147483647; 247 | files = ( 248 | 101DD6D01A052EDE00161F0D /* Main.storyboard in Resources */, 249 | 101DD6D51A052EDE00161F0D /* LaunchScreen.xib in Resources */, 250 | 101DD6D21A052EDE00161F0D /* Images.xcassets in Resources */, 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | 101DD6D81A052EDE00161F0D /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | /* End PBXResourcesBuildPhase section */ 262 | 263 | /* Begin PBXSourcesBuildPhase section */ 264 | 101DD6C11A052EDE00161F0D /* Sources */ = { 265 | isa = PBXSourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 101DD6CD1A052EDE00161F0D /* ViewController.swift in Sources */, 269 | 78C69A1D1A34C56F00B923C8 /* AlbumExtensions.swift in Sources */, 270 | 101DD6CB1A052EDE00161F0D /* AppDelegate.swift in Sources */, 271 | 78C69A191A33BD0B00B923C8 /* LibraryAPI.swift in Sources */, 272 | 785E1AA11A34F5D500C42E3B /* HorizontalScroller.swift in Sources */, 273 | 101DD6EC1A052F0E00161F0D /* HTTPClient.swift in Sources */, 274 | 78C69A171A33B00B00B923C8 /* AlbumView.swift in Sources */, 275 | 78C69A151A33AF6200B923C8 /* Album.swift in Sources */, 276 | 78C69A1B1A33C9EF00B923C8 /* PersistencyManager.swift in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | 101DD6D61A052EDE00161F0D /* Sources */ = { 281 | isa = PBXSourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | 101DD6E11A052EDE00161F0D /* BlueLibrarySwiftTests.swift in Sources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | /* End PBXSourcesBuildPhase section */ 289 | 290 | /* Begin PBXTargetDependency section */ 291 | 101DD6DC1A052EDE00161F0D /* PBXTargetDependency */ = { 292 | isa = PBXTargetDependency; 293 | target = 101DD6C41A052EDE00161F0D /* BlueLibrarySwift */; 294 | targetProxy = 101DD6DB1A052EDE00161F0D /* PBXContainerItemProxy */; 295 | }; 296 | /* End PBXTargetDependency section */ 297 | 298 | /* Begin PBXVariantGroup section */ 299 | 101DD6CE1A052EDE00161F0D /* Main.storyboard */ = { 300 | isa = PBXVariantGroup; 301 | children = ( 302 | 101DD6CF1A052EDE00161F0D /* Base */, 303 | ); 304 | name = Main.storyboard; 305 | sourceTree = ""; 306 | }; 307 | 101DD6D31A052EDE00161F0D /* LaunchScreen.xib */ = { 308 | isa = PBXVariantGroup; 309 | children = ( 310 | 101DD6D41A052EDE00161F0D /* Base */, 311 | ); 312 | name = LaunchScreen.xib; 313 | sourceTree = ""; 314 | }; 315 | /* End PBXVariantGroup section */ 316 | 317 | /* Begin XCBuildConfiguration section */ 318 | 101DD6E21A052EDE00161F0D /* Debug */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ALWAYS_SEARCH_USER_PATHS = NO; 322 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 323 | CLANG_CXX_LIBRARY = "libc++"; 324 | CLANG_ENABLE_MODULES = YES; 325 | CLANG_ENABLE_OBJC_ARC = YES; 326 | CLANG_WARN_BOOL_CONVERSION = YES; 327 | CLANG_WARN_CONSTANT_CONVERSION = YES; 328 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 329 | CLANG_WARN_EMPTY_BODY = YES; 330 | CLANG_WARN_ENUM_CONVERSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | COPY_PHASE_STRIP = NO; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_DYNAMIC_NO_PIC = NO; 340 | GCC_OPTIMIZATION_LEVEL = 0; 341 | GCC_PREPROCESSOR_DEFINITIONS = ( 342 | "DEBUG=1", 343 | "$(inherited)", 344 | ); 345 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_UNDECLARED_SELECTOR = YES; 349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 350 | GCC_WARN_UNUSED_FUNCTION = YES; 351 | GCC_WARN_UNUSED_VARIABLE = YES; 352 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 353 | MTL_ENABLE_DEBUG_INFO = YES; 354 | ONLY_ACTIVE_ARCH = YES; 355 | SDKROOT = iphoneos; 356 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 357 | TARGETED_DEVICE_FAMILY = "1,2"; 358 | }; 359 | name = Debug; 360 | }; 361 | 101DD6E31A052EDE00161F0D /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ALWAYS_SEARCH_USER_PATHS = NO; 365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 366 | CLANG_CXX_LIBRARY = "libc++"; 367 | CLANG_ENABLE_MODULES = YES; 368 | CLANG_ENABLE_OBJC_ARC = YES; 369 | CLANG_WARN_BOOL_CONVERSION = YES; 370 | CLANG_WARN_CONSTANT_CONVERSION = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INT_CONVERSION = YES; 375 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 376 | CLANG_WARN_UNREACHABLE_CODE = YES; 377 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 378 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 379 | COPY_PHASE_STRIP = YES; 380 | ENABLE_NS_ASSERTIONS = NO; 381 | ENABLE_STRICT_OBJC_MSGSEND = YES; 382 | GCC_C_LANGUAGE_STANDARD = gnu99; 383 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 384 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 385 | GCC_WARN_UNDECLARED_SELECTOR = YES; 386 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 387 | GCC_WARN_UNUSED_FUNCTION = YES; 388 | GCC_WARN_UNUSED_VARIABLE = YES; 389 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 390 | MTL_ENABLE_DEBUG_INFO = NO; 391 | SDKROOT = iphoneos; 392 | TARGETED_DEVICE_FAMILY = "1,2"; 393 | VALIDATE_PRODUCT = YES; 394 | }; 395 | name = Release; 396 | }; 397 | 101DD6E51A052EDE00161F0D /* Debug */ = { 398 | isa = XCBuildConfiguration; 399 | buildSettings = { 400 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 401 | INFOPLIST_FILE = BlueLibrarySwift/Info.plist; 402 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | }; 405 | name = Debug; 406 | }; 407 | 101DD6E61A052EDE00161F0D /* Release */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 411 | INFOPLIST_FILE = BlueLibrarySwift/Info.plist; 412 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 413 | PRODUCT_NAME = "$(TARGET_NAME)"; 414 | }; 415 | name = Release; 416 | }; 417 | 101DD6E81A052EDE00161F0D /* Debug */ = { 418 | isa = XCBuildConfiguration; 419 | buildSettings = { 420 | BUNDLE_LOADER = "$(TEST_HOST)"; 421 | FRAMEWORK_SEARCH_PATHS = ( 422 | "$(SDKROOT)/Developer/Library/Frameworks", 423 | "$(inherited)", 424 | ); 425 | GCC_PREPROCESSOR_DEFINITIONS = ( 426 | "DEBUG=1", 427 | "$(inherited)", 428 | ); 429 | INFOPLIST_FILE = BlueLibrarySwiftTests/Info.plist; 430 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 431 | PRODUCT_NAME = "$(TARGET_NAME)"; 432 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BlueLibrarySwift.app/BlueLibrarySwift"; 433 | }; 434 | name = Debug; 435 | }; 436 | 101DD6E91A052EDE00161F0D /* Release */ = { 437 | isa = XCBuildConfiguration; 438 | buildSettings = { 439 | BUNDLE_LOADER = "$(TEST_HOST)"; 440 | FRAMEWORK_SEARCH_PATHS = ( 441 | "$(SDKROOT)/Developer/Library/Frameworks", 442 | "$(inherited)", 443 | ); 444 | INFOPLIST_FILE = BlueLibrarySwiftTests/Info.plist; 445 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 446 | PRODUCT_NAME = "$(TARGET_NAME)"; 447 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BlueLibrarySwift.app/BlueLibrarySwift"; 448 | }; 449 | name = Release; 450 | }; 451 | /* End XCBuildConfiguration section */ 452 | 453 | /* Begin XCConfigurationList section */ 454 | 101DD6C01A052EDE00161F0D /* Build configuration list for PBXProject "BlueLibrarySwift" */ = { 455 | isa = XCConfigurationList; 456 | buildConfigurations = ( 457 | 101DD6E21A052EDE00161F0D /* Debug */, 458 | 101DD6E31A052EDE00161F0D /* Release */, 459 | ); 460 | defaultConfigurationIsVisible = 0; 461 | defaultConfigurationName = Release; 462 | }; 463 | 101DD6E41A052EDE00161F0D /* Build configuration list for PBXNativeTarget "BlueLibrarySwift" */ = { 464 | isa = XCConfigurationList; 465 | buildConfigurations = ( 466 | 101DD6E51A052EDE00161F0D /* Debug */, 467 | 101DD6E61A052EDE00161F0D /* Release */, 468 | ); 469 | defaultConfigurationIsVisible = 0; 470 | defaultConfigurationName = Release; 471 | }; 472 | 101DD6E71A052EDE00161F0D /* Build configuration list for PBXNativeTarget "BlueLibrarySwiftTests" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 101DD6E81A052EDE00161F0D /* Debug */, 476 | 101DD6E91A052EDE00161F0D /* Release */, 477 | ); 478 | defaultConfigurationIsVisible = 0; 479 | defaultConfigurationName = Release; 480 | }; 481 | /* End XCConfigurationList section */ 482 | }; 483 | rootObject = 101DD6BD1A052EDE00161F0D /* Project object */; 484 | } 485 | --------------------------------------------------------------------------------