afmotion 2.2.0 → 3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,73 @@
1
+ motion_require '../client_shared'
2
+
3
+ module AFMotion
4
+ module Serialization
5
+ def with_request_serializer(serializer_klass)
6
+ self.requestSerializer = serializer_klass.serializer
7
+ self
8
+ end
9
+
10
+ def with_response_serializer(serializer_klass)
11
+ self.responseSerializer = serializer_klass.serializer
12
+ self
13
+ end
14
+
15
+ def http!
16
+ with_request_serializer(AFHTTPRequestSerializer).
17
+ with_response_serializer(AFHTTPResponseSerializer)
18
+ end
19
+
20
+ def json!
21
+ with_request_serializer(AFJSONRequestSerializer).
22
+ with_response_serializer(AFJSONResponseSerializer)
23
+ end
24
+
25
+ def xml!
26
+ with_response_serializer(AFXMLParserResponseSerializer)
27
+ end
28
+
29
+ def plist!
30
+ with_request_serializer(AFPropertyListRequestSerializer).
31
+ with_response_serializer(AFPropertyListResponseSerializer)
32
+ end
33
+
34
+ def image!
35
+ with_response_serializer(AFImageResponseSerializer)
36
+ end
37
+ end
38
+ end
39
+
40
+ class AFHTTPSessionManager
41
+ include AFMotion::Serialization
42
+ include AFMotion::ClientShared
43
+
44
+ AFMotion::HTTP_METHODS.each do |method|
45
+ # EX client.get('my/resource.json')
46
+ define_method "#{method}", -> (path, options = {}, &callback) do
47
+ create_task(method, path, options, &callback)
48
+ end
49
+ end
50
+
51
+ # options = {parameters: , constructingBodyWithBlock: , success:, failure:}
52
+ def PUT(url_string, options = {})
53
+ parameters = options[:parameters]
54
+ block = options[:constructingBodyWithBlock]
55
+ progress = options[:progress_block]
56
+ success = options[:success]
57
+ failure = options[:failure]
58
+
59
+ request = self.requestSerializer.multipartFormRequestWithMethod("PUT", URLString: NSURL.URLWithString(url_string, relativeToURL: self.baseURL).absoluteString, parameters:parameters, constructingBodyWithBlock:block, error:nil)
60
+
61
+ task = self.dataTaskWithRequest(request, uploadProgress: progress, downloadProgress: nil, completionHandler: ->(response, responseObject, error) {
62
+ if error && failure
63
+ failure.call(task, error)
64
+ elsif success
65
+ success.call(task, responseObject)
66
+ end
67
+ })
68
+
69
+ task.resume
70
+
71
+ task
72
+ end
73
+ end
@@ -2,9 +2,9 @@ motion_require 'version'
2
2
 
3
3
  module AFMotion
4
4
  class HTTP
5
- def self.operation_manager
6
- @operation_manager ||= begin
7
- manager = AFHTTPRequestOperationManager.manager
5
+ def self.manager
6
+ @manager ||= begin
7
+ manager = AFHTTPSessionManager.manager
8
8
  configure_manager(manager)
9
9
  manager
10
10
  end
@@ -18,6 +18,7 @@ module AFMotion
18
18
  class JSON < HTTP
19
19
  def self.configure_manager(manager)
20
20
  manager.json!
21
+ manager.responseSerializer.readingOptions = NSJSONReadingMutableContainers
21
22
  end
22
23
  end
23
24
 
@@ -34,20 +35,36 @@ module AFMotion
34
35
  end
35
36
 
36
37
  class Image < HTTP
37
- def self.configure_manager(operation)
38
- operation.image!
38
+ def self.configure_manager(manager)
39
+ manager.image!
39
40
  end
40
41
  end
41
42
 
42
43
  [HTTP, JSON, XML, PLIST, Image].each do |base|
43
44
  AFMotion::HTTP_METHODS.each do |method_name|
44
- method_signature = "#{method_name.to_s.upcase}:parameters:success:failure:"
45
- base.define_singleton_method(method_name, -> (url, parameters = nil, &callback) do
46
- base.operation_manager.send(method_signature, url,
45
+ http_method = method_name.to_s.upcase
46
+
47
+ method_signature = "#{http_method}:parameters:headers:progress:success:failure:"
48
+ method_signature.gsub!("progress:", "") if http_method == "HEAD"
49
+
50
+ base.define_singleton_method(method_name, -> (url, options = {}, &callback) do
51
+ parameters = options.fetch(:params, {})
52
+ headers = options[:headers]
53
+ progress = options[:progress_block]
54
+
55
+ args = [ method_signature,
56
+ url,
47
57
  parameters,
48
- AFMotion::Operation.success_block_for_http_method(method_name, callback),
49
- AFMotion::Operation.failure_block(callback))
58
+ headers,
59
+ progress,
60
+ manager.success_block_for_http_method(method_name, callback),
61
+ manager.failure_block(callback)
62
+ ]
63
+
64
+ args.delete_at(4) if http_method == "HEAD" # HEAD doesn't take a progress arg
65
+
66
+ base.manager.send(*args)
50
67
  end)
51
68
  end
52
69
  end
53
- end
70
+ end
@@ -1,15 +1,9 @@
1
1
  module AFMotion
2
2
  class HTTPResult
3
- attr_accessor :operation, :object, :error, :task
3
+ attr_accessor :object, :error, :task
4
4
 
5
- def initialize(operation_or_task, responseObject, error)
6
- if defined?(NSURLSessionTask) && operation_or_task.is_a?(NSURLSessionTask) ||
7
- # cluser class ugh
8
- operation_or_task.class.to_s.include?("Task")
9
- self.task = operation_or_task
10
- else
11
- self.operation = operation_or_task
12
- end
5
+ def initialize(task, responseObject, error)
6
+ self.task = task
13
7
  self.object = responseObject
14
8
  self.error = error
15
9
  end
@@ -21,14 +15,23 @@ module AFMotion
21
15
  def failure?
22
16
  !!error
23
17
  end
18
+
19
+ # include this for backwards compatibility (?)
20
+ def operation
21
+ puts "HTTPResult#operation is deprecated and returns a task, switch to using #task"
22
+ task
23
+ end
24
24
 
25
- def body
26
- if task && task.currentRequest
27
- raise "Cannot call result.body of a task"
28
- end
29
- if operation && operation.responseString
30
- operation.responseString
25
+ def status_code
26
+ if self.task && self.task.response
27
+ self.task.response.statusCode
28
+ else
29
+ nil
31
30
  end
32
31
  end
32
+
33
+ def body
34
+ self.object
35
+ end
33
36
  end
34
37
  end
@@ -1,17 +1,12 @@
1
1
  module AFMotion
2
2
  module Operation
3
3
  module_function
4
- def for_request(ns_url_request, &callback)
5
- operation = AFHTTPRequestOperation.alloc.initWithRequest(ns_url_request)
6
- success_block = success_block_for_http_method(ns_url_request.HTTPMethod, callback)
7
- operation.setCompletionBlockWithSuccess(success_block, failure: failure_block(callback))
8
- operation
9
- end
10
4
 
11
5
  def success_block_for_http_method(http_method, callback)
12
6
  if http_method.downcase.to_sym == :head
13
7
  return lambda { |operation_or_task|
14
- AFMotion::HTTPResult.new(operation_or_task, nil, nil)
8
+ result = AFMotion::HTTPResult.new(operation_or_task, nil, nil)
9
+ callback.call(result)
15
10
  }
16
11
  end
17
12
 
@@ -23,53 +18,9 @@ module AFMotion
23
18
 
24
19
  def failure_block(callback)
25
20
  lambda { |operation_or_task, error|
26
- response_object = operation_or_task.is_a?(AFHTTPRequestOperation) ? operation_or_task.responseObject : nil
27
- result = AFMotion::HTTPResult.new(operation_or_task, response_object, error)
21
+ result = AFMotion::HTTPResult.new(operation_or_task, nil, error)
28
22
  callback.call(result)
29
23
  }
30
24
  end
31
25
  end
32
-
33
- module Serialization
34
- def with_request_serializer(serializer_klass)
35
- self.requestSerializer = serializer_klass.serializer
36
- self
37
- end
38
-
39
- def with_response_serializer(serializer_klass)
40
- self.responseSerializer = serializer_klass.serializer
41
- self
42
- end
43
-
44
- def http!
45
- with_request_serializer(AFHTTPRequestSerializer).
46
- with_response_serializer(AFHTTPResponseSerializer)
47
- end
48
-
49
- def json!
50
- with_request_serializer(AFJSONRequestSerializer).
51
- with_response_serializer(AFJSONResponseSerializer)
52
- end
53
-
54
- def xml!
55
- with_response_serializer(AFXMLParserResponseSerializer)
56
- end
57
-
58
- def plist!
59
- with_request_serializer(AFPropertyListRequestSerializer).
60
- with_response_serializer(AFPropertyListResponseSerializer)
61
- end
62
-
63
- def image!
64
- with_response_serializer(AFImageResponseSerializer)
65
- end
66
- end
67
- end
68
-
69
- class AFHTTPRequestOperation
70
- include AFMotion::Serialization
71
26
  end
72
-
73
- class AFHTTPRequestOperationManager
74
- include AFMotion::Serialization
75
- end
@@ -32,8 +32,6 @@ class AFHTTPRequestSerializer
32
32
  clearAuthorizationHeader
33
33
  elsif options[:username] && options[:password]
34
34
  setAuthorizationHeaderFieldWithUsername(options[:username], password: options[:password])
35
- elsif options[:token]
36
- setAuthorizationHeaderFieldWithToken(options[:token])
37
35
  else
38
36
  raise "Not a valid authorization hash: #{options.inspect}"
39
37
  end
@@ -1,5 +1,7 @@
1
- motion_require 'http_client'
2
1
  motion_require 'version'
2
+ motion_require 'client_shared'
3
+ motion_require 'session_client_dsl'
4
+ motion_require 'ext/AFHTTPSessionManager'
3
5
 
4
6
  =begin
5
7
  AFMotion::SessionClient.build("http://google.com") do |client|
@@ -21,13 +23,16 @@ module AFMotion
21
23
  # Returns an instance of AFHTTPRequestOperationManager
22
24
  def build(base_url, &block)
23
25
  dsl = AFMotion::SessionClientDSL.new(base_url)
24
- case block.arity
25
- when 0
26
- dsl.instance_eval(&block)
27
- when 1
28
- block.call(dsl)
26
+
27
+ if block_given?
28
+ case block.arity
29
+ when 0
30
+ dsl.instance_eval(&block)
31
+ when 1
32
+ block.call(dsl)
33
+ end
29
34
  end
30
-
35
+
31
36
  dsl.to_session_manager
32
37
  end
33
38
 
@@ -37,114 +42,8 @@ module AFMotion
37
42
  end
38
43
  end
39
44
  end
40
- end
41
-
42
- module AFMotion
43
- class SessionClientDSL < ClientDSL
44
- class Config
45
- attr_accessor :responseSerializer, :operationQueue, :requestSerializer, :sessionConfiguration
46
-
47
- class MockRequestSerializer
48
- attr_accessor :authorization
49
- end
50
-
51
- def requestSerializer
52
- @requestSerializer ||= MockRequestSerializer.new
53
- end
54
-
55
- def requestSerializer=(requestSerializer)
56
- if @requestSerializer && @requestSerializer.is_a?(MockRequestSerializer)
57
- requestSerializer.authorization = @requestSerializer.authorization
58
- end
59
- @requestSerializer = requestSerializer
60
- end
61
-
62
- def headers
63
- @headers ||= {}
64
- end
65
- end
66
-
67
- attr_accessor :operation_manager
68
- alias_method :config, :operation_manager
69
-
70
- def initialize(base_url)
71
- @base_url = base_url
72
- @operation_manager = Config.new
73
- end
74
-
75
- def to_session_manager
76
- session_manager = AFHTTPSessionManager.alloc.initWithBaseURL(@base_url.to_url,
77
- sessionConfiguration: config.sessionConfiguration)
78
- session_manager.responseSerializer = config.responseSerializer if config.responseSerializer
79
- if !config.requestSerializer.is_a?(Config::MockRequestSerializer)
80
- session_manager.requestSerializer = config.requestSerializer
81
- elsif config.requestSerializer.authorization
82
- session_manager.requestSerializer.authorization = config.requestSerializer.authorization
83
- end
84
- config.headers.each do |key, value|
85
- session_manager.requestSerializer.headers[key] = value
86
- end
87
- session_manager.operationQueue = config.operationQueue if config.operationQueue
88
- session_manager
89
- end
90
-
91
- SESSION_CONFIGURATION_SHORTHAND = {
92
- default: :defaultSessionConfiguration,
93
- ephemeral: :ephemeralSessionConfiguration,
94
- background: "backgroundSessionConfiguration:".to_sym
95
- }
96
-
97
- def session_configuration(session_configuration, identifier = nil)
98
- if session_configuration.is_a?(Symbol) || session_configuration.is_a?(String)
99
- method_signature = SESSION_CONFIGURATION_SHORTHAND[session_configuration.to_sym]
100
- ns_url_session_configuration = begin
101
- if identifier
102
- NSURLSessionConfiguration.send(method_signature, identifier)
103
- else
104
- NSURLSessionConfiguration.send(method_signature)
105
- end
106
- end
107
- self.config.sessionConfiguration = ns_url_session_configuration
108
- elsif session_configuration.is_a?(NSURLSessionConfiguration) ||
109
- # cluster class smh
110
- session_configuration.class.to_s.include?("URLSessionConfiguration")
111
- self.config.sessionConfiguration = session_configuration
112
- else
113
- raise "Invalid type for session_configuration; need Symbol, String, or NSURLSessionConfiguration, but got #{session_configuration.class}"
114
- end
115
- end
45
+
46
+ # These are now the same thing
47
+ class Client < SessionClient
116
48
  end
117
49
  end
118
-
119
- class AFHTTPSessionManager
120
- include AFMotion::ClientShared
121
-
122
- AFMotion::HTTP_METHODS.each do |method|
123
- # EX client.get('my/resource.json')
124
- define_method "#{method}", -> (path, parameters = {}, &callback) do
125
- create_task(method, path, parameters, &callback)
126
- end
127
- end
128
-
129
- # options = {parameters: , constructingBodyWithBlock: , success:, failure:}
130
- def PUT(url_string, options = {})
131
- parameters = options[:parameters]
132
- block = options[:constructingBodyWithBlock]
133
- success = options[:success]
134
- failure = options[:failure]
135
-
136
- request = self.requestSerializer.multipartFormRequestWithMethod("PUT", URLString: NSURL.URLWithString(url_string, relativeToURL: self.baseURL).absoluteString, parameters:parameters, constructingBodyWithBlock:block)
137
-
138
- task = self.dataTaskWithRequest(request, completionHandler: ->(response, responseObject, error) {
139
- if error && failure
140
- failure.call(task, error)
141
- elsif success
142
- success.call(task, responseObject)
143
- end
144
- })
145
-
146
- task.resume
147
-
148
- task
149
- end
150
- end
@@ -0,0 +1,143 @@
1
+ module AFMotion
2
+ class SessionClientDSL
3
+ class Config
4
+ attr_accessor :responseSerializer, :requestSerializer, :sessionConfiguration
5
+
6
+ class MockRequestSerializer
7
+ attr_accessor :authorization
8
+ end
9
+
10
+ def requestSerializer
11
+ @requestSerializer ||= MockRequestSerializer.new
12
+ end
13
+
14
+ def requestSerializer=(requestSerializer)
15
+ if @requestSerializer && @requestSerializer.is_a?(MockRequestSerializer)
16
+ requestSerializer.authorization = @requestSerializer.authorization
17
+ end
18
+ @requestSerializer = requestSerializer
19
+ end
20
+
21
+ def headers
22
+ @headers ||= {}
23
+ end
24
+ end
25
+
26
+ attr_accessor :config
27
+
28
+ def initialize(base_url)
29
+ @base_url = base_url
30
+ @config = Config.new
31
+ end
32
+
33
+ def to_session_manager
34
+ session_manager = AFHTTPSessionManager.alloc.initWithBaseURL(@base_url.to_url,
35
+ sessionConfiguration: config.sessionConfiguration)
36
+
37
+ session_manager.responseSerializer = config.responseSerializer if config.responseSerializer
38
+ if !config.requestSerializer.is_a?(Config::MockRequestSerializer)
39
+ session_manager.requestSerializer = config.requestSerializer
40
+ elsif config.requestSerializer.authorization
41
+ session_manager.requestSerializer.authorization = config.requestSerializer.authorization
42
+ end
43
+
44
+ config.headers.each do |key, value|
45
+ session_manager.requestSerializer.headers[key] = value
46
+ end
47
+ session_manager
48
+ end
49
+
50
+ SESSION_CONFIGURATION_SHORTHAND = {
51
+ default: :defaultSessionConfiguration,
52
+ ephemeral: :ephemeralSessionConfiguration,
53
+ background: (Object.const_defined?("UIDevice") && UIDevice.currentDevice.systemVersion.to_f >= 8.0 ? "backgroundSessionConfigurationWithIdentifier:" : "backgroundSessionConfiguration:").to_sym
54
+ }
55
+
56
+ def session_configuration(session_configuration, identifier = nil)
57
+ if session_configuration.is_a?(Symbol) || session_configuration.is_a?(String)
58
+ method_signature = SESSION_CONFIGURATION_SHORTHAND[session_configuration.to_sym]
59
+ ns_url_session_configuration = begin
60
+ if identifier
61
+ NSURLSessionConfiguration.send(method_signature, identifier)
62
+ else
63
+ NSURLSessionConfiguration.send(method_signature)
64
+ end
65
+ end
66
+ self.config.sessionConfiguration = ns_url_session_configuration
67
+ elsif session_configuration.is_a?(NSURLSessionConfiguration) ||
68
+ # cluster class smh
69
+ session_configuration.class.to_s.include?("URLSessionConfiguration")
70
+ self.config.sessionConfiguration = session_configuration
71
+ else
72
+ raise "Invalid type for session_configuration; need Symbol, String, or NSURLSessionConfiguration, but got #{session_configuration.class}"
73
+ end
74
+ end
75
+
76
+ def header(header, value)
77
+ @headers ||= {}
78
+ @headers[header] = value
79
+ apply_header(header, value)
80
+ end
81
+
82
+ def authorization(options = {})
83
+ @authorization = options
84
+ apply_authorization(options)
85
+ end
86
+
87
+ OPERATION_TO_REQUEST_SERIALIZER = {
88
+ json: AFJSONRequestSerializer,
89
+ plist: AFPropertyListRequestSerializer
90
+ }
91
+ def request_serializer(serializer)
92
+ if serializer.is_a?(Symbol) || serializer.is_a?(String)
93
+ config.requestSerializer = OPERATION_TO_REQUEST_SERIALIZER[serializer.to_sym].serializer
94
+ elsif serializer.is_a?(Class)
95
+ config.requestSerializer = serializer.serializer
96
+ else
97
+ config.requestSerializer = serializer
98
+ end
99
+ reapply_options
100
+ end
101
+
102
+ OPERATION_TO_RESPONSE_SERIALIZER = {
103
+ json: AFJSONResponseSerializer,
104
+ xml: AFXMLParserResponseSerializer,
105
+ plist: AFPropertyListResponseSerializer,
106
+ image: AFImageResponseSerializer,
107
+ http: AFHTTPResponseSerializer,
108
+ form: AFHTTPResponseSerializer
109
+ }
110
+ def response_serializer(serializer)
111
+ write_json_options = true
112
+ if serializer.is_a?(Symbol) || serializer.is_a?(String)
113
+ config.responseSerializer = OPERATION_TO_RESPONSE_SERIALIZER[serializer.to_sym].serializer
114
+ elsif serializer.is_a?(Class)
115
+ config.responseSerializer = serializer.serializer
116
+ else
117
+ config.responseSerializer = serializer
118
+ write_json_options = false
119
+ end
120
+ af_serializer = config.responseSerializer
121
+ if af_serializer.is_a?(AFJSONResponseSerializer) && write_json_options
122
+ af_serializer.readingOptions = NSJSONReadingMutableContainers
123
+ end
124
+ af_serializer
125
+ end
126
+
127
+ private
128
+
129
+ def reapply_options
130
+ @headers.each{ |h,v| apply_header(h, v) } unless @headers.nil?
131
+ apply_authorization(@authorization) unless @authorization.nil?
132
+ end
133
+
134
+ def apply_header(header, value)
135
+ config.headers[header] = value
136
+ end
137
+
138
+ def apply_authorization(options)
139
+ config.requestSerializer.authorization = options
140
+ end
141
+
142
+ end
143
+ end