forked from thisandagain/conduit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DIYConduit.m
213 lines (177 loc) · 4.45 KB
/
DIYConduit.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
//
// DIYConduit.m
// conduit
//
// Created by Andrew Sliwinski on 6/17/12.
// Copyright (c) 2012 DIY, Co. All rights reserved.
//
#import "DIYConduit.h"
//
@interface DIYConduit ()
@property (nonatomic, retain) DIYConduitBridge *bridge;
@end
//
@implementation DIYConduit
@synthesize delegate = _delegate;
@synthesize webView = _webView;
@synthesize bridge = _bridge;
@synthesize headers = _headers;
#pragma mark - Init
- (void)_init
{
// Setup
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
_bridge = [[DIYConduitBridge alloc] init];
_headers = [[NSMutableDictionary alloc] init];
// Assign delegates
self.bridge.delegate = self;
self.webView.delegate = self.bridge;
// Add to view
[self addSubview:self.webView];
}
- (id)init
{
if (self = [super init])
{
[self _init];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self _init];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self _init];
}
return self;
}
#pragma mark - Public methods
/**
* Loads a NSURLRequest into the web view with custom headers appended.
*
* @param {NSURLRequest} Request
*
* @return {void}
*/
- (void)loadRequest:(NSURLRequest *)request
{
[self.webView loadRequest:[self generateMutableRequestWithRequest:request andHeaders:self.headers]];
[self.bridge pushRequestHeaders:self.headers];
}
/**
* Loads HTML into the web view from a string.
*
* @param {NSString} HTML
* @param {NSURL} Base URL reference (usually set to "nil")
*
* @return {void}
*/
- (void)loadHTMLString:(NSString *)html baseURL:(NSURL *)baseURL
{
[self.webView loadHTMLString:html baseURL:baseURL];
}
/**
* Adds a custom header to be reflected in every subsequent request.
*
* @param {NSString} Header key (e.g. @"x-api-key")
* @param {NSString} Header value (e.g. @"mykeygoeshere")
*
* @return {void}
*/
- (void)addHeader:(NSString *)key withValue:(NSString *)value
{
[self.headers setValue:value forKey:[key lowercaseString]];
}
/**
* Removes a header.
*
* @param {NSString} Header key (e.g. @"x-api-key")
*
* @return {void}
*/
- (void)removeHeader:(NSString *)key
{
[self.headers setValue:nil forKey:[key lowercaseString]];
}
/**
* Sends a message to the bridge.
*
* @param {NSString} Message
*
* @return {void}
*/
- (void)sendMessage:(NSString *)message
{
[self.bridge sendMessage:message toWebView:self.webView];
}
/**
* Resets the bridge message queue.
*
* @return {void}
*/
- (void)resetMessageQueue
{
[bridge resetQueue];
}
#pragma mark - Private methods
- (NSMutableURLRequest *)generateMutableRequestWithRequest:(NSURLRequest *)_request andHeaders:(NSDictionary *)_headers
{
NSMutableURLRequest *mutableRequest = [[_request mutableCopy] autorelease];
for (NSString *key in self.headers)
{
[mutableRequest setValue:[self.headers valueForKey:key] forHTTPHeaderField:key];
}
return mutableRequest;
}
#pragma mark - UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// Check for local request & bypass custom headers logic
if ([[[request URL] absoluteString] isEqualToString:@"about:blank"])
{
return true;
}
// Storage objects
BOOL customHeadersExist = true;
NSDictionary *existingHeaders = [request allHTTPHeaderFields];
// Check that custom headers exist
for (NSString *key in self.headers) {
if ([existingHeaders objectForKey:key] == nil) {
customHeadersExist = false;
break;
}
}
// If not, append them to the request
if (!customHeadersExist) {
[self loadRequest:request];
return false;
}
return true;
}
#pragma mark - WebViewJavascriptBridge
- (void)javascriptBridge:(DIYConduitBridge *)bridge receivedMessage:(NSString *)message fromWebView:(UIWebView *)webView
{
[self.delegate conduit:self receivedMessage:message];
}
#pragma mark - Dealloc
- (void)releaseObjects
{
self.delegate = nil;
[_webView release]; _webView = nil;
[_bridge release]; _bridge = nil;
[_headers release]; _headers = nil;
}
- (void)dealloc
{
[self releaseObjects];
[super dealloc];
}
@end