lanekit 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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