├── BlockLooper.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── .gitignore
├── BlockLooper.podspec
├── BlockLooperTests
├── Info.plist
└── BlockLooperTests.swift
├── LICENSE
├── BlockLooper
├── AppDelegate.swift
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── Launch Screen.xib
├── ViewController.swift
└── Source
│ └── BlockLooper.swift
└── README.md
/BlockLooper.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
--------------------------------------------------------------------------------
/BlockLooper.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "BlockLooper"
4 | s.version = "0.0.3"
5 | s.summary = "Helper class that lets you loop a closure until you tell it to stop. In Swift."
6 |
7 | s.homepage = "http://github.com/al7/BlockLooper"
8 | s.license = "MIT"
9 | s.author = { "Alex Leite" => "admin@al7dev.com" }
10 | s.ios.deployment_target = "8.0"
11 | s.osx.deployment_target = "10.9"
12 | s.source = { :git => "https://github.com/al7/BlockLooper.git", :tag => "0.0.3" }
13 | s.source_files = "BlockLooper/Source", "BlockLooper/Source/**/*.{h,m,swift}"
14 | s.requires_arc = true
15 |
16 | end
17 |
--------------------------------------------------------------------------------
/BlockLooperTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/BlockLooperTests/BlockLooperTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BlockLooperTests.swift
3 | // BlockLooperTests
4 | //
5 | // Created by Alexandre Leite on 5/29/15.
6 | // Copyright (c) 2015 Alexandre Leite. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class BlockLooperTests: 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 | Copyright (c) 2015 - Alex Leite (al7dev)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/BlockLooper/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // BlockLooper
4 | //
5 | // Created by Alexandre Leite on 5/29/15.
6 | // Copyright (c) 2015 Alexandre Leite. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
19 | self.window?.rootViewController = ViewController()
20 | self.window?.makeKeyAndVisible()
21 |
22 | return true
23 | }
24 |
25 | func applicationWillResignActive(application: UIApplication) {
26 |
27 | }
28 |
29 | func applicationDidEnterBackground(application: UIApplication) {
30 |
31 | }
32 |
33 | func applicationWillEnterForeground(application: UIApplication) {
34 |
35 | }
36 |
37 | func applicationDidBecomeActive(application: UIApplication) {
38 |
39 | }
40 |
41 | func applicationWillTerminate(application: UIApplication) {
42 |
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/BlockLooper/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 | }
--------------------------------------------------------------------------------
/BlockLooper/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 0.0.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | Launch Screen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | BlockLooper
2 | =====================
3 |
4 | ### About
5 |
6 | This is a helper class that allows you to easily execute a closure on a loop, at a certain rate, until you tell it to stop. It's is very useful for creating, for instance, quick sequential animations using *UIKit*. To better understand what this class does, run the sample project on the iPhone Simulator, then look at the source code.
7 |
8 | ### Sample Code
9 |
10 | Using this class is pretty simple and straight-forward. You just need to run the following code:
11 |
12 | ```swift
13 | //-- Scheduling a loopable closure:
14 |
15 | BlockLooper.executeBlockWithRate(0.5) {
16 |
17 | // loop code goes here...
18 |
19 | return true
20 | }
21 | ```
22 |
23 | In the function call, ```rate``` corresponds to the *NSTimeInterval* value of the frequency in which the closure should be looped. In the sample above, the closure will be executed once, and then stop.
24 |
25 | The closure signature is: ```() -> Bool ```, where the return value indicates if the loop should be interrupted. In the sample below, we are running the loop 10 times until it stops:
26 |
27 | ```swift
28 | var loopI = 0
29 |
30 | BlockLooper.executeBlockWithRate(0.5) {
31 |
32 | println("Loop i: \(loopI)")
33 | ++loopI
34 |
35 | return (loopI >= 10)
36 | }
37 | ```
38 | You can also execute multiple loops at once.
39 |
40 | ### How to install
41 |
42 | To use this control, you can either copy the [*BlockLooper.swift*](BlockLooper/Source/BlockLooper.swift) file to your project (you can find it at the '[Source](BlockLooper/Source)' folder of this project), or add the following pod to your Podfile, using CocoaPods 0.36 and up:
43 |
44 | ```
45 | pod 'BlockLooper'
46 | ```
47 |
48 | ### License
49 |
50 | This component is available under MIT license.
51 |
--------------------------------------------------------------------------------
/BlockLooper/Launch Screen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/BlockLooper/ViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2015 - Alex Leite (al7dev)
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
13 | all 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
21 | THE SOFTWARE.
22 |
23 | */
24 |
25 | import UIKit
26 |
27 | class ViewController: UIViewController {
28 |
29 | var sampleSquare: UIView?
30 | var columns = 5
31 | var rows: Int { return self.columns }
32 | var cellSpan: CGFloat = 0.0
33 |
34 | override func loadView() {
35 | self.view = UIView(frame: UIScreen.mainScreen().bounds)
36 | self.view.backgroundColor = UIColor.whiteColor()
37 |
38 | let screenSize = UIScreen.mainScreen().bounds.size
39 | let squareSpan = min(screenSize.width, screenSize.height) - 100.0
40 |
41 | self.sampleSquare = UIView(frame: CGRectMake(0.0, 0.0, squareSpan, squareSpan))
42 | self.sampleSquare!.layer.borderColor = UIColor.blueColor().CGColor
43 | self.sampleSquare!.layer.borderWidth = 1.0
44 | self.sampleSquare!.center = self.view.center
45 |
46 | self.view.addSubview(self.sampleSquare!)
47 | }
48 |
49 | override func viewDidLoad() {
50 | super.viewDidLoad()
51 | self.cellSpan = self.sampleSquare!.frame.size.width / CGFloat(self.columns)
52 | }
53 |
54 | override func viewDidAppear(animated: Bool) {
55 | super.viewDidAppear(animated)
56 | self.performSampleCode()
57 | }
58 |
59 | override func didReceiveMemoryWarning() {
60 | super.didReceiveMemoryWarning()
61 |
62 | }
63 |
64 | //MARK- Helper Methods
65 |
66 | private func performSampleCode() {
67 |
68 | //--- HERE IS HOW TO USE THE COMPONENT:
69 | var cellI = 0
70 | let totalCells = self.columns * self.rows
71 | let colorIncrement = 1.0 / CGFloat(totalCells)
72 | var currentColorShade: CGFloat = 0.0
73 |
74 | BlockLooper.executeBlockWithRate(0.1) {
75 | [unowned self] in
76 |
77 | let columnI = cellI % self.columns
78 | let rowI = Int(floor(Double(cellI) / Double(self.rows)))
79 |
80 | let newLabel = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: self.cellSpan, height: self.cellSpan))
81 | newLabel.textColor = UIColor.blueColor()
82 | newLabel.font = UIFont.boldSystemFontOfSize(24.0)
83 | newLabel.textAlignment = .Center
84 | newLabel.text = "\(cellI)"
85 | newLabel.layer.borderColor = UIColor.blueColor().CGColor
86 | newLabel.layer.borderWidth = 1.0
87 | newLabel.backgroundColor = UIColor(red: 0.0, green: 1.0, blue: 0.0, alpha: currentColorShade)
88 | newLabel.alpha = 0.0
89 |
90 | self.sampleSquare!.addSubview(newLabel)
91 |
92 | UIView.animateWithDuration(0.5) {
93 | var newFrame = newLabel.frame
94 | newFrame.origin.x = self.cellSpan * CGFloat(columnI)
95 | newFrame.origin.y = self.cellSpan * CGFloat(rowI)
96 | newLabel.frame = newFrame
97 | newLabel.alpha = 1.0
98 | }
99 |
100 | cellI++
101 | currentColorShade += colorIncrement
102 | if cellI >= totalCells {
103 | return true
104 | }
105 | else {
106 | return false
107 | }
108 | }
109 | }
110 |
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/BlockLooper/Source/BlockLooper.swift:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2015 - Alex Leite (al7dev)
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
13 | all 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
21 | THE SOFTWARE.
22 |
23 | */
24 |
25 | import Foundation
26 |
27 | public typealias LoopableBlock = () -> Bool
28 |
29 | public class BlockLooper {
30 |
31 | public class func executeBlockWithRate(rate: NSTimeInterval, block: LoopableBlock) {
32 | let newLoopInstance = LoopInstance(rate: rate, loopableBlock: block)
33 | newLoopInstance.index = self.helper.nextIndex
34 | newLoopInstance.endBlock = {
35 | loopInstance, event in
36 | BlockLooper.helper.scheduleLoopInstance(loopInstance)
37 | }
38 | BlockLooper.helper.scheduleLoopInstance(newLoopInstance)
39 | }
40 |
41 | //MARK- Singleton Methods
42 |
43 | static var helper: Helper {
44 | struct Static {
45 | static var instance: Helper?
46 | static var token: dispatch_once_t = 0
47 | }
48 |
49 | dispatch_once(&Static.token) {
50 | Static.instance = Helper()
51 | }
52 |
53 | return Static.instance!
54 | }
55 |
56 | //MARK- Helper Classes
57 |
58 | class Helper {
59 | private var loopIndex = 0
60 | var nextIndex: Int {
61 | let result = self.loopIndex
62 | ++self.loopIndex
63 | return result
64 | }
65 |
66 | var loopInstances: LoopInstances = []
67 |
68 | func isLoopInstanceScheduled(loopInstance: LoopInstance) -> Bool {
69 | if let _ = self.loopInstances.indexOf(loopInstance) {
70 | return true
71 | }
72 | return false
73 | }
74 |
75 | func scheduleLoopInstance(loopInstance: LoopInstance) -> Bool {
76 | if self.isLoopInstanceScheduled(loopInstance) == false {
77 | self.loopInstances.append(loopInstance)
78 | loopInstance.start()
79 | return true
80 | }
81 | return false
82 | }
83 |
84 | func dismissLoopInstance(loopInstance: LoopInstance) -> Bool {
85 | if let index = self.loopInstances.indexOf(loopInstance) {
86 | loopInstance.cleanUp()
87 | self.loopInstances.removeAtIndex(index)
88 | return true
89 | }
90 | return false
91 | }
92 | }
93 |
94 | class LoopInstance: NSObject {
95 | private var rate: NSTimeInterval = 1.0
96 | private var loopableBlock: LoopableBlock
97 | private var loopTimer: NSTimer?
98 | private var hasStarted = false
99 |
100 | var index = 0
101 | var startBlock: LoopLifecycleBlock?
102 | var stepBlock: LoopLifecycleBlock?
103 | var endBlock: LoopLifecycleBlock?
104 |
105 | init(rate: NSTimeInterval, loopableBlock: LoopableBlock!) {
106 | self.rate = rate
107 | self.loopableBlock = loopableBlock
108 | }
109 |
110 | func start() {
111 | if hasStarted == false {
112 | hasStarted = true
113 |
114 | if let startBlock = self.startBlock {
115 | startBlock(loopInstance: self, event: .Start)
116 | }
117 |
118 | self.loopTimer = NSTimer.scheduledTimerWithTimeInterval(self.rate, target: self, selector: "onTimerTick:", userInfo: nil, repeats: true)
119 | }
120 | else {
121 | if let timer = self.loopTimer {
122 | timer.fire()
123 | }
124 | }
125 | }
126 |
127 | func stop() {
128 | if let timer = self.loopTimer {
129 | timer.invalidate()
130 | }
131 | }
132 |
133 | func cleanUp() {
134 | self.loopTimer = nil
135 | self.startBlock = nil
136 | self.stepBlock = nil
137 | self.endBlock = nil
138 | }
139 |
140 | func onTimerTick(sender: NSTimer!) {
141 | if let stepBlock = self.stepBlock {
142 | stepBlock(loopInstance: self, event: .Step)
143 | }
144 |
145 | let shouldFinish = self.loopableBlock()
146 | if shouldFinish {
147 | self.stop()
148 | if let endBlock = self.endBlock {
149 | endBlock(loopInstance: self, event: .End)
150 | }
151 | }
152 | }
153 | }
154 |
155 | enum LoopLifecycleEvent {
156 | case Start, Step, End
157 | }
158 |
159 | typealias LoopInstances = [LoopInstance]
160 | typealias LoopLifecycleBlock = (loopInstance: LoopInstance, event: LoopLifecycleEvent) -> Void
161 | }
162 |
163 | func ==(lhs: BlockLooper.LoopInstance, rhs: BlockLooper.LoopInstance) -> Bool {
164 | return lhs.index == rhs.index
165 | }
166 |
--------------------------------------------------------------------------------
/BlockLooper.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1320AB9C1B196C5B008B5188 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1320AB9B1B196C5B008B5188 /* AppDelegate.swift */; };
11 | 1320AB9E1B196C5B008B5188 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1320AB9D1B196C5B008B5188 /* ViewController.swift */; };
12 | 1320ABA31B196C5B008B5188 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1320ABA21B196C5B008B5188 /* Images.xcassets */; };
13 | 1320ABB21B196C5B008B5188 /* BlockLooperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1320ABB11B196C5B008B5188 /* BlockLooperTests.swift */; };
14 | 1320ABBD1B19750A008B5188 /* BlockLooper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1320ABBC1B19750A008B5188 /* BlockLooper.swift */; };
15 | 1320ABC81B1F4C5A008B5188 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1320ABC71B1F4C5A008B5188 /* Launch Screen.xib */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXContainerItemProxy section */
19 | 1320ABAC1B196C5B008B5188 /* PBXContainerItemProxy */ = {
20 | isa = PBXContainerItemProxy;
21 | containerPortal = 1320AB8E1B196C5B008B5188 /* Project object */;
22 | proxyType = 1;
23 | remoteGlobalIDString = 1320AB951B196C5B008B5188;
24 | remoteInfo = BlockLooper;
25 | };
26 | /* End PBXContainerItemProxy section */
27 |
28 | /* Begin PBXFileReference section */
29 | 1320AB961B196C5B008B5188 /* BlockLooper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BlockLooper.app; sourceTree = BUILT_PRODUCTS_DIR; };
30 | 1320AB9A1B196C5B008B5188 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 1320AB9B1B196C5B008B5188 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
32 | 1320AB9D1B196C5B008B5188 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
33 | 1320ABA21B196C5B008B5188 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
34 | 1320ABAB1B196C5B008B5188 /* BlockLooperTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BlockLooperTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 1320ABB01B196C5B008B5188 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
36 | 1320ABB11B196C5B008B5188 /* BlockLooperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockLooperTests.swift; sourceTree = ""; };
37 | 1320ABBC1B19750A008B5188 /* BlockLooper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockLooper.swift; sourceTree = ""; };
38 | 1320ABC71B1F4C5A008B5188 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = ""; };
39 | /* End PBXFileReference section */
40 |
41 | /* Begin PBXFrameworksBuildPhase section */
42 | 1320AB931B196C5B008B5188 /* Frameworks */ = {
43 | isa = PBXFrameworksBuildPhase;
44 | buildActionMask = 2147483647;
45 | files = (
46 | );
47 | runOnlyForDeploymentPostprocessing = 0;
48 | };
49 | 1320ABA81B196C5B008B5188 /* Frameworks */ = {
50 | isa = PBXFrameworksBuildPhase;
51 | buildActionMask = 2147483647;
52 | files = (
53 | );
54 | runOnlyForDeploymentPostprocessing = 0;
55 | };
56 | /* End PBXFrameworksBuildPhase section */
57 |
58 | /* Begin PBXGroup section */
59 | 1320AB8D1B196C5B008B5188 = {
60 | isa = PBXGroup;
61 | children = (
62 | 1320AB981B196C5B008B5188 /* BlockLooper */,
63 | 1320ABAE1B196C5B008B5188 /* BlockLooperTests */,
64 | 1320AB971B196C5B008B5188 /* Products */,
65 | );
66 | sourceTree = "";
67 | };
68 | 1320AB971B196C5B008B5188 /* Products */ = {
69 | isa = PBXGroup;
70 | children = (
71 | 1320AB961B196C5B008B5188 /* BlockLooper.app */,
72 | 1320ABAB1B196C5B008B5188 /* BlockLooperTests.xctest */,
73 | );
74 | name = Products;
75 | sourceTree = "";
76 | };
77 | 1320AB981B196C5B008B5188 /* BlockLooper */ = {
78 | isa = PBXGroup;
79 | children = (
80 | 1320ABBB1B196D16008B5188 /* Source */,
81 | 1320AB9B1B196C5B008B5188 /* AppDelegate.swift */,
82 | 1320AB9D1B196C5B008B5188 /* ViewController.swift */,
83 | 1320ABA21B196C5B008B5188 /* Images.xcassets */,
84 | 1320AB991B196C5B008B5188 /* Supporting Files */,
85 | 1320ABC71B1F4C5A008B5188 /* Launch Screen.xib */,
86 | );
87 | path = BlockLooper;
88 | sourceTree = "";
89 | };
90 | 1320AB991B196C5B008B5188 /* Supporting Files */ = {
91 | isa = PBXGroup;
92 | children = (
93 | 1320AB9A1B196C5B008B5188 /* Info.plist */,
94 | );
95 | name = "Supporting Files";
96 | sourceTree = "";
97 | };
98 | 1320ABAE1B196C5B008B5188 /* BlockLooperTests */ = {
99 | isa = PBXGroup;
100 | children = (
101 | 1320ABB11B196C5B008B5188 /* BlockLooperTests.swift */,
102 | 1320ABAF1B196C5B008B5188 /* Supporting Files */,
103 | );
104 | path = BlockLooperTests;
105 | sourceTree = "";
106 | };
107 | 1320ABAF1B196C5B008B5188 /* Supporting Files */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 1320ABB01B196C5B008B5188 /* Info.plist */,
111 | );
112 | name = "Supporting Files";
113 | sourceTree = "";
114 | };
115 | 1320ABBB1B196D16008B5188 /* Source */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 1320ABBC1B19750A008B5188 /* BlockLooper.swift */,
119 | );
120 | path = Source;
121 | sourceTree = "";
122 | };
123 | /* End PBXGroup section */
124 |
125 | /* Begin PBXNativeTarget section */
126 | 1320AB951B196C5B008B5188 /* BlockLooper */ = {
127 | isa = PBXNativeTarget;
128 | buildConfigurationList = 1320ABB51B196C5B008B5188 /* Build configuration list for PBXNativeTarget "BlockLooper" */;
129 | buildPhases = (
130 | 1320AB921B196C5B008B5188 /* Sources */,
131 | 1320AB931B196C5B008B5188 /* Frameworks */,
132 | 1320AB941B196C5B008B5188 /* Resources */,
133 | );
134 | buildRules = (
135 | );
136 | dependencies = (
137 | );
138 | name = BlockLooper;
139 | productName = BlockLooper;
140 | productReference = 1320AB961B196C5B008B5188 /* BlockLooper.app */;
141 | productType = "com.apple.product-type.application";
142 | };
143 | 1320ABAA1B196C5B008B5188 /* BlockLooperTests */ = {
144 | isa = PBXNativeTarget;
145 | buildConfigurationList = 1320ABB81B196C5B008B5188 /* Build configuration list for PBXNativeTarget "BlockLooperTests" */;
146 | buildPhases = (
147 | 1320ABA71B196C5B008B5188 /* Sources */,
148 | 1320ABA81B196C5B008B5188 /* Frameworks */,
149 | 1320ABA91B196C5B008B5188 /* Resources */,
150 | );
151 | buildRules = (
152 | );
153 | dependencies = (
154 | 1320ABAD1B196C5B008B5188 /* PBXTargetDependency */,
155 | );
156 | name = BlockLooperTests;
157 | productName = BlockLooperTests;
158 | productReference = 1320ABAB1B196C5B008B5188 /* BlockLooperTests.xctest */;
159 | productType = "com.apple.product-type.bundle.unit-test";
160 | };
161 | /* End PBXNativeTarget section */
162 |
163 | /* Begin PBXProject section */
164 | 1320AB8E1B196C5B008B5188 /* Project object */ = {
165 | isa = PBXProject;
166 | attributes = {
167 | LastSwiftMigration = 0700;
168 | LastSwiftUpdateCheck = 0700;
169 | LastUpgradeCheck = 0700;
170 | ORGANIZATIONNAME = "Alexandre Leite";
171 | TargetAttributes = {
172 | 1320AB951B196C5B008B5188 = {
173 | CreatedOnToolsVersion = 6.3;
174 | };
175 | 1320ABAA1B196C5B008B5188 = {
176 | CreatedOnToolsVersion = 6.3;
177 | TestTargetID = 1320AB951B196C5B008B5188;
178 | };
179 | };
180 | };
181 | buildConfigurationList = 1320AB911B196C5B008B5188 /* Build configuration list for PBXProject "BlockLooper" */;
182 | compatibilityVersion = "Xcode 3.2";
183 | developmentRegion = English;
184 | hasScannedForEncodings = 0;
185 | knownRegions = (
186 | en,
187 | Base,
188 | );
189 | mainGroup = 1320AB8D1B196C5B008B5188;
190 | productRefGroup = 1320AB971B196C5B008B5188 /* Products */;
191 | projectDirPath = "";
192 | projectRoot = "";
193 | targets = (
194 | 1320AB951B196C5B008B5188 /* BlockLooper */,
195 | 1320ABAA1B196C5B008B5188 /* BlockLooperTests */,
196 | );
197 | };
198 | /* End PBXProject section */
199 |
200 | /* Begin PBXResourcesBuildPhase section */
201 | 1320AB941B196C5B008B5188 /* Resources */ = {
202 | isa = PBXResourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | 1320ABA31B196C5B008B5188 /* Images.xcassets in Resources */,
206 | 1320ABC81B1F4C5A008B5188 /* Launch Screen.xib in Resources */,
207 | );
208 | runOnlyForDeploymentPostprocessing = 0;
209 | };
210 | 1320ABA91B196C5B008B5188 /* Resources */ = {
211 | isa = PBXResourcesBuildPhase;
212 | buildActionMask = 2147483647;
213 | files = (
214 | );
215 | runOnlyForDeploymentPostprocessing = 0;
216 | };
217 | /* End PBXResourcesBuildPhase section */
218 |
219 | /* Begin PBXSourcesBuildPhase section */
220 | 1320AB921B196C5B008B5188 /* Sources */ = {
221 | isa = PBXSourcesBuildPhase;
222 | buildActionMask = 2147483647;
223 | files = (
224 | 1320ABBD1B19750A008B5188 /* BlockLooper.swift in Sources */,
225 | 1320AB9E1B196C5B008B5188 /* ViewController.swift in Sources */,
226 | 1320AB9C1B196C5B008B5188 /* AppDelegate.swift in Sources */,
227 | );
228 | runOnlyForDeploymentPostprocessing = 0;
229 | };
230 | 1320ABA71B196C5B008B5188 /* Sources */ = {
231 | isa = PBXSourcesBuildPhase;
232 | buildActionMask = 2147483647;
233 | files = (
234 | 1320ABB21B196C5B008B5188 /* BlockLooperTests.swift in Sources */,
235 | );
236 | runOnlyForDeploymentPostprocessing = 0;
237 | };
238 | /* End PBXSourcesBuildPhase section */
239 |
240 | /* Begin PBXTargetDependency section */
241 | 1320ABAD1B196C5B008B5188 /* PBXTargetDependency */ = {
242 | isa = PBXTargetDependency;
243 | target = 1320AB951B196C5B008B5188 /* BlockLooper */;
244 | targetProxy = 1320ABAC1B196C5B008B5188 /* PBXContainerItemProxy */;
245 | };
246 | /* End PBXTargetDependency section */
247 |
248 | /* Begin XCBuildConfiguration section */
249 | 1320ABB31B196C5B008B5188 /* Debug */ = {
250 | isa = XCBuildConfiguration;
251 | buildSettings = {
252 | ALWAYS_SEARCH_USER_PATHS = NO;
253 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
254 | CLANG_CXX_LIBRARY = "libc++";
255 | CLANG_ENABLE_MODULES = YES;
256 | CLANG_ENABLE_OBJC_ARC = YES;
257 | CLANG_WARN_BOOL_CONVERSION = YES;
258 | CLANG_WARN_CONSTANT_CONVERSION = YES;
259 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
260 | CLANG_WARN_EMPTY_BODY = YES;
261 | CLANG_WARN_ENUM_CONVERSION = YES;
262 | CLANG_WARN_INT_CONVERSION = YES;
263 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
264 | CLANG_WARN_UNREACHABLE_CODE = YES;
265 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
266 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
267 | COPY_PHASE_STRIP = NO;
268 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
269 | ENABLE_STRICT_OBJC_MSGSEND = YES;
270 | ENABLE_TESTABILITY = YES;
271 | GCC_C_LANGUAGE_STANDARD = gnu99;
272 | GCC_DYNAMIC_NO_PIC = NO;
273 | GCC_NO_COMMON_BLOCKS = YES;
274 | GCC_OPTIMIZATION_LEVEL = 0;
275 | GCC_PREPROCESSOR_DEFINITIONS = (
276 | "DEBUG=1",
277 | "$(inherited)",
278 | );
279 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
280 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
281 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
282 | GCC_WARN_UNDECLARED_SELECTOR = YES;
283 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
284 | GCC_WARN_UNUSED_FUNCTION = YES;
285 | GCC_WARN_UNUSED_VARIABLE = YES;
286 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
287 | MTL_ENABLE_DEBUG_INFO = YES;
288 | ONLY_ACTIVE_ARCH = YES;
289 | SDKROOT = iphoneos;
290 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
291 | TARGETED_DEVICE_FAMILY = "1,2";
292 | };
293 | name = Debug;
294 | };
295 | 1320ABB41B196C5B008B5188 /* Release */ = {
296 | isa = XCBuildConfiguration;
297 | buildSettings = {
298 | ALWAYS_SEARCH_USER_PATHS = NO;
299 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
300 | CLANG_CXX_LIBRARY = "libc++";
301 | CLANG_ENABLE_MODULES = YES;
302 | CLANG_ENABLE_OBJC_ARC = YES;
303 | CLANG_WARN_BOOL_CONVERSION = YES;
304 | CLANG_WARN_CONSTANT_CONVERSION = YES;
305 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
306 | CLANG_WARN_EMPTY_BODY = YES;
307 | CLANG_WARN_ENUM_CONVERSION = YES;
308 | CLANG_WARN_INT_CONVERSION = YES;
309 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
310 | CLANG_WARN_UNREACHABLE_CODE = YES;
311 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
312 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
313 | COPY_PHASE_STRIP = NO;
314 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
315 | ENABLE_NS_ASSERTIONS = NO;
316 | ENABLE_STRICT_OBJC_MSGSEND = YES;
317 | GCC_C_LANGUAGE_STANDARD = gnu99;
318 | GCC_NO_COMMON_BLOCKS = YES;
319 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
320 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
321 | GCC_WARN_UNDECLARED_SELECTOR = YES;
322 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
323 | GCC_WARN_UNUSED_FUNCTION = YES;
324 | GCC_WARN_UNUSED_VARIABLE = YES;
325 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
326 | MTL_ENABLE_DEBUG_INFO = NO;
327 | SDKROOT = iphoneos;
328 | TARGETED_DEVICE_FAMILY = "1,2";
329 | VALIDATE_PRODUCT = YES;
330 | };
331 | name = Release;
332 | };
333 | 1320ABB61B196C5B008B5188 /* Debug */ = {
334 | isa = XCBuildConfiguration;
335 | buildSettings = {
336 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
337 | INFOPLIST_FILE = BlockLooper/Info.plist;
338 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
339 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.$(PRODUCT_NAME:rfc1034identifier)";
340 | PRODUCT_NAME = "$(TARGET_NAME)";
341 | };
342 | name = Debug;
343 | };
344 | 1320ABB71B196C5B008B5188 /* Release */ = {
345 | isa = XCBuildConfiguration;
346 | buildSettings = {
347 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
348 | INFOPLIST_FILE = BlockLooper/Info.plist;
349 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
350 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.$(PRODUCT_NAME:rfc1034identifier)";
351 | PRODUCT_NAME = "$(TARGET_NAME)";
352 | };
353 | name = Release;
354 | };
355 | 1320ABB91B196C5B008B5188 /* Debug */ = {
356 | isa = XCBuildConfiguration;
357 | buildSettings = {
358 | BUNDLE_LOADER = "$(TEST_HOST)";
359 | FRAMEWORK_SEARCH_PATHS = (
360 | "$(SDKROOT)/Developer/Library/Frameworks",
361 | "$(inherited)",
362 | );
363 | GCC_PREPROCESSOR_DEFINITIONS = (
364 | "DEBUG=1",
365 | "$(inherited)",
366 | );
367 | INFOPLIST_FILE = BlockLooperTests/Info.plist;
368 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
369 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.$(PRODUCT_NAME:rfc1034identifier)";
370 | PRODUCT_NAME = "$(TARGET_NAME)";
371 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BlockLooper.app/BlockLooper";
372 | };
373 | name = Debug;
374 | };
375 | 1320ABBA1B196C5B008B5188 /* Release */ = {
376 | isa = XCBuildConfiguration;
377 | buildSettings = {
378 | BUNDLE_LOADER = "$(TEST_HOST)";
379 | FRAMEWORK_SEARCH_PATHS = (
380 | "$(SDKROOT)/Developer/Library/Frameworks",
381 | "$(inherited)",
382 | );
383 | INFOPLIST_FILE = BlockLooperTests/Info.plist;
384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
385 | PRODUCT_BUNDLE_IDENTIFIER = "com.al7dev.$(PRODUCT_NAME:rfc1034identifier)";
386 | PRODUCT_NAME = "$(TARGET_NAME)";
387 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BlockLooper.app/BlockLooper";
388 | };
389 | name = Release;
390 | };
391 | /* End XCBuildConfiguration section */
392 |
393 | /* Begin XCConfigurationList section */
394 | 1320AB911B196C5B008B5188 /* Build configuration list for PBXProject "BlockLooper" */ = {
395 | isa = XCConfigurationList;
396 | buildConfigurations = (
397 | 1320ABB31B196C5B008B5188 /* Debug */,
398 | 1320ABB41B196C5B008B5188 /* Release */,
399 | );
400 | defaultConfigurationIsVisible = 0;
401 | defaultConfigurationName = Release;
402 | };
403 | 1320ABB51B196C5B008B5188 /* Build configuration list for PBXNativeTarget "BlockLooper" */ = {
404 | isa = XCConfigurationList;
405 | buildConfigurations = (
406 | 1320ABB61B196C5B008B5188 /* Debug */,
407 | 1320ABB71B196C5B008B5188 /* Release */,
408 | );
409 | defaultConfigurationIsVisible = 0;
410 | defaultConfigurationName = Release;
411 | };
412 | 1320ABB81B196C5B008B5188 /* Build configuration list for PBXNativeTarget "BlockLooperTests" */ = {
413 | isa = XCConfigurationList;
414 | buildConfigurations = (
415 | 1320ABB91B196C5B008B5188 /* Debug */,
416 | 1320ABBA1B196C5B008B5188 /* Release */,
417 | );
418 | defaultConfigurationIsVisible = 0;
419 | defaultConfigurationName = Release;
420 | };
421 | /* End XCConfigurationList section */
422 | };
423 | rootObject = 1320AB8E1B196C5B008B5188 /* Project object */;
424 | }
425 |
--------------------------------------------------------------------------------