lanekit 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +62 -2
  3. data/lib/lanekit/generate/model.rb +0 -9
  4. data/lib/lanekit/generate/provider.rb +2 -10
  5. data/lib/lanekit/generate/urbanairship.rb +53 -0
  6. data/lib/lanekit/generate.rb +21 -0
  7. data/lib/lanekit/new.rb +19 -0
  8. data/lib/lanekit/version.rb +1 -1
  9. data/lib/lanekit.rb +37 -4
  10. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/Controllers/LKAppDelegate.m +20 -0
  11. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/Controllers/LKDetailViewController.h +12 -0
  12. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/Controllers/LKDetailViewController.m +68 -0
  13. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/Controllers/LKMasterViewController.h +13 -0
  14. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/Controllers/LKMasterViewController.m +122 -0
  15. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/Resources/Base.lproj/Main_iPad.storyboard +139 -0
  16. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/Resources/Base.lproj/Main_iPhone.storyboard +104 -0
  17. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/{lanekit-ios-project-Info.plist → Supporting Files/lanekit-ios-project-Info.plist } +4 -0
  18. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project.xcodeproj/project.pbxproj +86 -14
  19. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project.xcodeproj/xcuserdata/larry.xcuserdatad/xcschemes/lanekit-ios-project.xcscheme +96 -0
  20. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project.xcodeproj/xcuserdata/larry.xcuserdatad/xcschemes/xcschememanagement.plist +27 -0
  21. data/lib/template/lanekit-ios-project/lanekit-ios-project.xcworkspace/xcshareddata/lanekit-ios-project.xccheckout +41 -0
  22. data/lib/template/lanekit-ios-project/lanekit-ios-project.xcworkspace/xcuserdata/larry.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  23. metadata +24 -10
  24. data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/LKAppDelegate.m +0 -45
  25. /data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/{LKAppDelegate.h → Controllers/LKAppDelegate.h} +0 -0
  26. /data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/{Images.xcassets → Resources/Images.xcassets}/AppIcon.appiconset/Contents.json +0 -0
  27. /data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/{Images.xcassets → Resources/Images.xcassets}/LaunchImage.launchimage/Contents.json +0 -0
  28. /data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/{en.lproj → Resources/en.lproj}/InfoPlist.strings +0 -0
  29. /data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/{lanekit-ios-project-Prefix.pch → Supporting Files/lanekit-ios-project-Prefix.pch} +0 -0
  30. /data/lib/template/lanekit-ios-project/lanekit-ios-project/lanekit-ios-project/{main.m → Supporting Files/main.m} +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzEwYjAyOTk2ZTQ5NjY4ZWZmYjljMGE4ZGQ1NmM0ODQyYTBmZDBjZQ==
4
+ ZWEwMTViOWNmYjliMjYxMWNjZDFlYjhhNTc5MTBlZmFkZmRkZGZiMA==
5
5
  data.tar.gz: !binary |-
6
- NTFlNDVjMTYxMjliMjY3OWFmNWI1MTg1ZWE5ZDRhZDBiNDEyMzA3NA==
6
+ NmRmOTQxYTI4YzczZjRjMTc1ZDlmYTNjYzRjMjE0ZjFiNGI1NThhMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NTljNmNlNWRlMTUxY2U0MzQyNWVkNDMzY2MyNjhiNjFiZmIwNGUyNjBjZGU2
10
- Mjk3ZTI0ODc3ODczOGM5YWJiNzJiOTQ2N2NkMmU2MmUyZWJjYTE3NDk3ZGQ3
11
- OTMyZDg3N2YwYzhlZWQwNWFlMjA2MmEzOGNkNzE5NzQ4YmM3NTA=
9
+ M2NjM2FhYjNlMDVmZDJkZjJiYzA4MTgzMWE5MzU5OGQ2ZTgyZjA2YTgzNWNk
10
+ M2VjODM5NzFmNjgwNTg0YjUxMGZhOGEyYWQ2ZTFlMTQ4ZTg1NTFmZTg5ZWFj
11
+ OTZiYjc0NTczM2U3ZDdmN2JmYmIxYmY2ZTU3NTRjMjQ0Y2ZkZTI=
12
12
  data.tar.gz: !binary |-
13
- M2Y0NGJlOTM1YjM0ZjI0MWExY2MzNTk2N2NkNWViNGYyZjY5NmE4MTNiNmJk
14
- ZDFlYjhkOGI0ZWVhNzNjZDVlMWY4NzQyMDk0MmVmMTM4ZmJiZjcxMzJlZTE4
15
- YWM2MGM1MzkwYzk2ODIwNDY4YjVkZTdjZTBjYzZiNGZiMWNjMTY=
13
+ Mzk0NTIzZWIxMjk1NWJiMmZiN2IzZmIzZTAxNDkyNTUyYWFlMDhmNWVlYmM1
14
+ OWE1N2I1N2M4YzhkY2M4M2VmNzEwZDRmZjIxOWU3Njg1YjRmM2M1ZTc3NTgw
15
+ NmRiODNmNDMzNTg1MGU4YjUxYWM5YjNkOWU1N2VjNmI0NDA5ZTg=
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## LaneKit
2
2
 
3
- LaneKit is an iOS Objective-C code generator for integration with RestKit. It generates
3
+ LaneKit is an iOS Objective-C code generator for integration with [RestKit](https://github.com/RestKit/RestKit). It generates
4
4
  models, resource providers, and full iOS apps with mimimal effort. There is support for unit testing with SenTestingKit
5
5
  including fixtures and tests. LaneKit is a command line app written in Ruby and packaged as a Ruby Gem.
6
6
 
@@ -13,7 +13,7 @@ including fixtures and tests. LaneKit is a command line app written in Ruby and
13
13
  * consistent Objective-C code
14
14
  * unit tests
15
15
  * test fixtures in JSON and Objective-C
16
- * iOS app creation fully integrated with CocoaPods and RestKit
16
+ * iOS app creation fully integrated with [CocoaPods](https://github.com/CocoaPods/CocoaPods) and RestKit, and .gitignore file
17
17
  * tested code
18
18
  * rapid development
19
19
  * enhanced productivity of junior developers
@@ -217,6 +217,66 @@ and here is a unit test that was generated in Models/VideoTest.m by LaneKit:
217
217
  ### Create a new iOS app fully integrated with CocoaPods and RestKit.
218
218
 
219
219
  $ lanekit new SportsFrames
220
+ create SportsFrames
221
+ create SportsFrames/Podfile
222
+ create SportsFrames/lanekit-ios-project.xcworkspace/contents.xcworkspacedata
223
+ create SportsFrames/lanekit-ios-project.xcworkspace/xcshareddata/lanekit-ios-project.xccheckout
224
+ create SportsFrames/lanekit-ios-project.xcworkspace/xcuserdata/larry.xcuserdatad/UserInterfaceState.xcuserstate
225
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project.xcodeproj/project.pbxproj
226
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project.xcodeproj/project.xcworkspace/contents.xcworkspacedata
227
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project.xcodeproj/xcuserdata/larry.xcuserdatad/xcschemes/lanekit-ios-project.xcscheme
228
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project.xcodeproj/xcuserdata/larry.xcuserdatad/xcschemes/xcschememanagement.plist
229
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Controllers/LKAppDelegate.h
230
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Controllers/LKAppDelegate.m
231
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Controllers/LKDetailViewController.h
232
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Controllers/LKDetailViewController.m
233
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Controllers/LKMasterViewController.h
234
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Controllers/LKMasterViewController.m
235
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Resources/Base.lproj/Main_iPad.storyboard
236
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Resources/Base.lproj/Main_iPhone.storyboard
237
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Resources/Images.xcassets/AppIcon.appiconset/Contents.json
238
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Resources/Images.xcassets/LaunchImage.launchimage/Contents.json
239
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Resources/en.lproj/InfoPlist.strings
240
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Supporting Files/lanekit-ios-project-Info.plist
241
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Supporting Files/lanekit-ios-project-Prefix.pch
242
+ create SportsFrames/lanekit-ios-project/lanekit-ios-project/Supporting Files/main.m
243
+ create SportsFrames/lanekit-ios-project/lanekit-ios-projectTests/en.lproj/InfoPlist.strings
244
+ create SportsFrames/lanekit-ios-project/lanekit-ios-projectTests/lanekit-ios-projectTests-Info.plist
245
+ create SportsFrames/lanekit-ios-project/lanekit-ios-projectTests/lanekit-ios-projectTests.m
246
+ create SportsFrames/.gitignore
247
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames
248
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames
249
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames/Supporting Files/SportsFrames-Info.plist
250
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames/Supporting Files/SportsFrames-Prefix.pch
251
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames.xcodeproj
252
+ update /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames.xcodeproj/project.pbxproj
253
+ update /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames.xcodeproj/project.xcworkspace/contents.xcworkspacedata
254
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames.xcodeproj/xcuserdata/larry.xcuserdatad/xcschemes/SportsFrames.xcscheme
255
+ update /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames.xcodeproj/xcuserdata/larry.xcuserdatad/xcschemes/SportsFrames.xcscheme
256
+ update /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFrames.xcodeproj/xcuserdata/larry.xcuserdatad/xcschemes/xcschememanagement.plist
257
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFramesTests
258
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFramesTests/SportsFramesTests-Info.plist
259
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames/SportsFramesTests/SportsFramesTests.m
260
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames.xcworkspace
261
+ update /Users/larry/Projects/lanekit/SportsFrames/SportsFrames.xcworkspace/contents.xcworkspacedata
262
+ rename /Users/larry/Projects/lanekit/SportsFrames/SportsFrames.xcworkspace/xcshareddata/SportsFrames.xccheckout
263
+ update /Users/larry/Projects/lanekit/SportsFrames/SportsFrames.xcworkspace/xcshareddata/SportsFrames.xccheckout
264
+ update /Users/larry/Projects/lanekit/SportsFrames/Podfile
265
+ Installing CocoaPods for RestKit
266
+ [in /Users/larry/Projects/lanekit/SportsFrames]
267
+ Analyzing dependencies
268
+ Downloading dependencies
269
+ Installing AFNetworking (1.3.3)
270
+ Installing RestKit (0.20.3)
271
+ Installing SOCKit (1.1)
272
+ Installing TransitionKit (1.1.1)
273
+ Generating Pods project
274
+ Integrating client project
275
+ clean /Users/larry/Projects/lanekit/SportsFrames/SportsFrames.xcworkspace
276
+
277
+ ### Add the [Urban Airship](https://github.com/urbanairship/ios-library) CocoaPods Pod to the project.
278
+
279
+ $ lanekit generate pod UrbanAirship-iOS-SDK
220
280
 
221
281
  ### Sample App
222
282
  The SportsFrames app is a fully functional sample app using RestKit created to demonstrate the use of LaneKit in a real world app. It
@@ -46,11 +46,6 @@ module LaneKit
46
46
  self.initialize_model
47
47
  self.create_model_folders
48
48
  self.create_model_files
49
- self.update_xcode_project
50
- end
51
-
52
- def self.source_root
53
- File.dirname('./')
54
49
  end
55
50
 
56
51
  no_tasks {
@@ -65,10 +60,6 @@ module LaneKit
65
60
  @tests_models_folder = "Classes/Tests/Models"
66
61
 
67
62
  end
68
-
69
- def source_paths
70
- LaneKit.template_folders
71
- end
72
63
 
73
64
  def create_model_folders
74
65
  empty_directory @models_folder
@@ -3,7 +3,7 @@ module LaneKit
3
3
 
4
4
  include Thor::Actions
5
5
 
6
- desc "provider [options] NAME MODEL_NAME URL", "Generates an Objective-C resource provider for RestKit including unit tests"
6
+ desc "provider [options] NAME MODEL_NAME [URL]", "Generates an Objective-C resource provider for RestKit including unit tests"
7
7
  long_desc <<-LONGDESC
8
8
  Generates the Objective-C code for a resource provider that is compatible with RestKit. It also generates test fixtures and unit tests.\n
9
9
  NAME: the name of the provider\n
@@ -11,7 +11,7 @@ module LaneKit
11
11
  URL: the HTTP URL to the data\n
12
12
  LONGDESC
13
13
 
14
- def provider(name, model_name, url)
14
+ def provider(name, model_name, url=nil)
15
15
  @using_core_data = options[:use_core_data]
16
16
  #puts " using Core Data: #{@using_core_data}"
17
17
  #puts " name: #{name}"
@@ -28,10 +28,6 @@ module LaneKit
28
28
  self.create_provider_folders
29
29
  self.create_provider_files
30
30
  end
31
-
32
- def self.source_root
33
- File.dirname('./')
34
- end
35
31
 
36
32
  no_commands do
37
33
 
@@ -46,10 +42,6 @@ module LaneKit
46
42
  @provider_file_name = @provider_name
47
43
  end
48
44
 
49
- def source_paths
50
- LaneKit.template_folders
51
- end
52
-
53
45
  def create_provider_folders
54
46
  empty_directory @providers_folder
55
47
  end
@@ -0,0 +1,53 @@
1
+ module LaneKit
2
+ class Generate
3
+
4
+ include Thor::Actions
5
+
6
+ desc "urbanairship", "Generates classes for Urban Airship integration"
7
+ def urbanairship()
8
+ LaneKit.add_pod_to_podfile('UrbanAirship-iOS-SDK')
9
+ end
10
+
11
+ no_commands do
12
+
13
+ def initialize_provider
14
+ @providers_folder = "Classes/Controllers"
15
+
16
+ # Resource Provider Base Class
17
+ @provider_base_name = "LKResourceProvider"
18
+ @provider_base_class_name = "LKResourceProvider"
19
+ @provider_base_file_name = "LKResourceProvider"
20
+
21
+ @provider_file_name = @provider_name
22
+ end
23
+
24
+ def create_provider_folders
25
+ empty_directory @providers_folder
26
+ end
27
+
28
+ def create_provider_files
29
+ # 1) Create the base resource provider
30
+ # Create the .h file
31
+ source = "provider_base.h.erb"
32
+ target = File.join(@providers_folder, "#{@provider_base_file_name}.h")
33
+ template(source, target, @@template_opts)
34
+
35
+ # Create the .m file
36
+ source = "provider_base.m.erb"
37
+ target = File.join(@providers_folder, "#{@provider_base_file_name}.m")
38
+ template(source, target, @@template_opts)
39
+
40
+ # 2) Create the resource provider
41
+ # Create the .h file
42
+ source = "provider.h.erb"
43
+ target = File.join(@providers_folder, "#{@provider_file_name}.h")
44
+ template(source, target, @@template_opts)
45
+
46
+ # Create the .m file
47
+ source = "provider.m.erb"
48
+ target = File.join(@providers_folder, "#{@provider_file_name}.m")
49
+ template(source, target, @@template_opts)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -3,7 +3,27 @@ class LaneKit::Generate < Thor
3
3
  @@lanekit_version = LaneKit::VERSION;
4
4
  @@generate_date = Date.today.to_s
5
5
 
6
+ def self.source_root
7
+ File.dirname('./')
8
+ end
9
+
10
+ desc "pod POD_NAME", "Adds a CocoaPods pod to the Podfile"
11
+ def pod(pod_name)
12
+ pod_name = pod_name.strip
13
+ validate_message = LaneKit.validate_pod_name(pod_name)
14
+ if validate_message
15
+ puts "***error: #{validate_message}"
16
+ return
17
+ end
18
+
19
+ LaneKit.add_pod_to_podfile(pod_name)
20
+ end
21
+
6
22
  no_tasks do
23
+ def source_paths
24
+ LaneKit.template_folders
25
+ end
26
+
7
27
  def update_xcode_project
8
28
  xcworkspace_path = ""
9
29
  Xcodeproj::Workspace.new_from_xcworkspace(xcworkspace_path)
@@ -18,6 +38,7 @@ class LaneKit::Generate < Thor
18
38
 
19
39
  require 'lanekit/generate/model'
20
40
  require 'lanekit/generate/provider'
41
+ require 'lanekit/generate/urbanairship'
21
42
 
22
43
  class_option :use_core_data, :type => :boolean, :default => false, :banner => "generate code compatible with Core Data (the default is false)", :aliases => "-c" # option --use_core_data=true
23
44
  end
data/lib/lanekit/new.rb CHANGED
@@ -43,6 +43,7 @@ module LaneKit
43
43
  @original_wd = Dir.pwd
44
44
 
45
45
  self.create_project
46
+ self.add_gitignore
46
47
  self.change_filenames(@app_path_full, @app_name, @ios_template_name)
47
48
  self.change_bundle_id(@bundle_id) if @bundle_id != nil
48
49
  self.add_cocoapods
@@ -86,6 +87,24 @@ module LaneKit
86
87
  end
87
88
  end
88
89
 
90
+ def add_gitignore
91
+ # Download the .gitignore file from GitHub
92
+ require 'net/https'
93
+ ignore_file_uri = URI("http://raw.github.com/github/gitignore/master/Objective-C.gitignore")
94
+ ignore_file_path = File.join(@app_path, ".gitignore")
95
+ say_status :create, ignore_file_path
96
+
97
+ response = Net::HTTP.start(ignore_file_uri.host, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
98
+ http.get ignore_file_uri.request_uri
99
+ end
100
+
101
+ require_text = response.body
102
+ open(ignore_file_path, "wb") do |file|
103
+ file.write(require_text)
104
+ end
105
+
106
+ end
107
+
89
108
  def create_project
90
109
  source = @ios_template_name
91
110
  destination = @app_path
@@ -1,3 +1,3 @@
1
1
  module LaneKit
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  end
data/lib/lanekit.rb CHANGED
@@ -15,10 +15,29 @@ module LaneKit
15
15
  [@template_folder]
16
16
  end
17
17
 
18
- # Returns an app name from a folder path. App names are lower case
19
- # "Tracker" => "tracker", "~/Projects/Runner" => "runner"
18
+ # Adds a pod file line to a CocoaPods Podfile
19
+ def self.add_pod_to_podfile(pod_name)
20
+ podfile_path = File.expand_path('Podfile')
21
+ if !File.exists?(podfile_path)
22
+ puts "Can't find Podfile #{podfile_path}"
23
+ return
24
+ end
25
+
26
+ if !self.does_text_exist_in_file?(podfile_path, pod_name)
27
+ open(podfile_path, 'a') do |file|
28
+ file.puts "pod '#{pod_name}'"
29
+ end
30
+
31
+ system "pod install"
32
+ else
33
+ puts "The pod '#{pod_name}' already exists in Podfile"
34
+ end
35
+ end
36
+
37
+ # Returns an app name from a folder path.
38
+ # "Tracker" => "Tracker", "~/Projects/Runner" => "Runner"
20
39
  def self.derive_app_name(app_path)
21
- app_name = File.basename(app_path).to_s.downcase
40
+ app_name = File.basename(app_path).to_s
22
41
  end
23
42
 
24
43
  # Model names are lower case
@@ -40,7 +59,12 @@ module LaneKit
40
59
  file_name = name.to_s.capitalize
41
60
  file_name
42
61
  end
43
-
62
+
63
+ def self.does_text_exist_in_file?(file_path, text)
64
+ found_text = open(file_path) { |f| f.grep(/#{text}/) }
65
+ exists = found_text && found_text.count > 0
66
+ end
67
+
44
68
  def self.objective_c_type(type_name)
45
69
  type = @@objc_types[type_name]
46
70
  return type if type
@@ -121,6 +145,15 @@ module LaneKit
121
145
  return nil
122
146
  end
123
147
 
148
+ def self.validate_pod_name(pod_name)
149
+ if pod_name.length < 2
150
+ return "pod name must be at least two characters long"
151
+ elsif pod_name.include? " "
152
+ return "pod name cannot include spaces"
153
+ end
154
+ return nil
155
+ end
156
+
124
157
  def self.validate_bundle_id(bundle_id)
125
158
  if bundle_id.length < 2
126
159
  return "bundle id must be at least two characters long"
@@ -0,0 +1,20 @@
1
+ //
2
+ // LKAppDelegate.m
3
+ //
4
+
5
+ #import "LKAppDelegate.h"
6
+
7
+ @implementation LKAppDelegate
8
+
9
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
10
+ {
11
+ // Override point for customization after application launch.
12
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
13
+ UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
14
+ UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
15
+ splitViewController.delegate = (id)navigationController.topViewController;
16
+ }
17
+ return YES;
18
+ }
19
+
20
+ @end
@@ -0,0 +1,12 @@
1
+ //
2
+ // LKDetailViewController.h
3
+ //
4
+
5
+ #import <UIKit/UIKit.h>
6
+
7
+ @interface LKDetailViewController : UIViewController <UISplitViewControllerDelegate>
8
+
9
+ @property (strong, nonatomic) id detailItem;
10
+
11
+ @property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
12
+ @end
@@ -0,0 +1,68 @@
1
+ //
2
+ // LKDetailViewController.m
3
+ //
4
+
5
+ #import "LKDetailViewController.h"
6
+
7
+ @interface LKDetailViewController ()
8
+ @property (strong, nonatomic) UIPopoverController *masterPopoverController;
9
+ - (void)configureView;
10
+ @end
11
+
12
+ @implementation LKDetailViewController
13
+
14
+ #pragma mark - Managing the detail item
15
+
16
+ - (void)setDetailItem:(id)newDetailItem
17
+ {
18
+ if (_detailItem != newDetailItem) {
19
+ _detailItem = newDetailItem;
20
+
21
+ // Update the view.
22
+ [self configureView];
23
+ }
24
+
25
+ if (self.masterPopoverController != nil) {
26
+ [self.masterPopoverController dismissPopoverAnimated:YES];
27
+ }
28
+ }
29
+
30
+ - (void)configureView
31
+ {
32
+ // Update the user interface for the detail item.
33
+
34
+ if (self.detailItem) {
35
+ self.detailDescriptionLabel.text = [self.detailItem description];
36
+ }
37
+ }
38
+
39
+ - (void)viewDidLoad
40
+ {
41
+ [super viewDidLoad];
42
+ // Do any additional setup after loading the view, typically from a nib.
43
+ [self configureView];
44
+ }
45
+
46
+ - (void)didReceiveMemoryWarning
47
+ {
48
+ [super didReceiveMemoryWarning];
49
+ // Dispose of any resources that can be recreated.
50
+ }
51
+
52
+ #pragma mark - Split view
53
+
54
+ - (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
55
+ {
56
+ barButtonItem.title = NSLocalizedString(@"Master", @"Master");
57
+ [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
58
+ self.masterPopoverController = popoverController;
59
+ }
60
+
61
+ - (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
62
+ {
63
+ // Called when the view is shown again in the split view, invalidating the button and popover controller.
64
+ [self.navigationItem setLeftBarButtonItem:nil animated:YES];
65
+ self.masterPopoverController = nil;
66
+ }
67
+
68
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // LKMasterViewController.h
3
+ //
4
+
5
+ #import <UIKit/UIKit.h>
6
+
7
+ @class LKDetailViewController;
8
+
9
+ @interface LKMasterViewController : UITableViewController
10
+
11
+ @property (strong, nonatomic) LKDetailViewController *detailViewController;
12
+
13
+ @end
@@ -0,0 +1,122 @@
1
+ //
2
+ // LKMasterViewController.m
3
+ //
4
+
5
+ #import "LKMasterViewController.h"
6
+
7
+ #import "LKDetailViewController.h"
8
+
9
+ @interface LKMasterViewController () {
10
+ NSMutableArray *_objects;
11
+ }
12
+ @end
13
+
14
+ @implementation LKMasterViewController
15
+
16
+ - (void)awakeFromNib
17
+ {
18
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
19
+ self.clearsSelectionOnViewWillAppear = NO;
20
+ self.preferredContentSize = CGSizeMake(320.0, 600.0);
21
+ }
22
+ [super awakeFromNib];
23
+ }
24
+
25
+ - (void)viewDidLoad
26
+ {
27
+ [super viewDidLoad];
28
+ // Do any additional setup after loading the view, typically from a nib.
29
+ self.navigationItem.leftBarButtonItem = self.editButtonItem;
30
+
31
+ UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
32
+ self.navigationItem.rightBarButtonItem = addButton;
33
+ self.detailViewController = (LKDetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
34
+ }
35
+
36
+ - (void)didReceiveMemoryWarning
37
+ {
38
+ [super didReceiveMemoryWarning];
39
+ // Dispose of any resources that can be recreated.
40
+ }
41
+
42
+ - (void)insertNewObject:(id)sender
43
+ {
44
+ if (!_objects) {
45
+ _objects = [[NSMutableArray alloc] init];
46
+ }
47
+ [_objects insertObject:[NSDate date] atIndex:0];
48
+ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
49
+ [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
50
+ }
51
+
52
+ #pragma mark - Table View
53
+
54
+ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
55
+ {
56
+ return 1;
57
+ }
58
+
59
+ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
60
+ {
61
+ return _objects.count;
62
+ }
63
+
64
+ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
65
+ {
66
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
67
+
68
+ NSDate *object = _objects[indexPath.row];
69
+ cell.textLabel.text = [object description];
70
+ return cell;
71
+ }
72
+
73
+ - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
74
+ {
75
+ // Return NO if you do not want the specified item to be editable.
76
+ return YES;
77
+ }
78
+
79
+ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
80
+ {
81
+ if (editingStyle == UITableViewCellEditingStyleDelete) {
82
+ [_objects removeObjectAtIndex:indexPath.row];
83
+ [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
84
+ } else if (editingStyle == UITableViewCellEditingStyleInsert) {
85
+ // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
86
+ }
87
+ }
88
+
89
+ /*
90
+ // Override to support rearranging the table view.
91
+ - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
92
+ {
93
+ }
94
+ */
95
+
96
+ /*
97
+ // Override to support conditional rearranging of the table view.
98
+ - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
99
+ {
100
+ // Return NO if you do not want the item to be re-orderable.
101
+ return YES;
102
+ }
103
+ */
104
+
105
+ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
106
+ {
107
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
108
+ NSDate *object = _objects[indexPath.row];
109
+ self.detailViewController.detailItem = object;
110
+ }
111
+ }
112
+
113
+ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
114
+ {
115
+ if ([[segue identifier] isEqualToString:@"showDetail"]) {
116
+ NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
117
+ NSDate *object = _objects[indexPath.row];
118
+ [[segue destinationViewController] setDetailItem:object];
119
+ }
120
+ }
121
+
122
+ @end