├── Example
├── iOS Example
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── Prefix.pch
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── AppDelegate.h
│ ├── WebViewController.h
│ ├── main.m
│ ├── AppDelegate.m
│ └── WebViewController.m
└── iOS Example.xcodeproj
│ ├── project.xcworkspace
│ └── contents.xcworkspacedata
│ └── project.pbxproj
├── NSEtcHosts.xcworkspace
├── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── contents.xcworkspacedata
├── LICENSE.md
├── NSEtcHosts
├── NSEtcHosts.h
├── EtcHostsURLProtocol.h
└── EtcHostsURLProtocol.m
└── README.md
/Example/iOS Example/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NSEtcHosts.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/iOS Example/Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_3_0
10 | #warning "This project uses features only available in iOS SDK 3.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/Example/iOS Example/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" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/iOS Example/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/NSEtcHosts.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
9 |
10 |
12 |
13 |
15 |
16 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Mattt (https://mat.tt)
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 |
--------------------------------------------------------------------------------
/NSEtcHosts/NSEtcHosts.h:
--------------------------------------------------------------------------------
1 | // NSEtcHosts.h
2 | //
3 | // Copyright (c) 2014 Mattt (https://mat.tt)
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 | #ifndef _NSETCHOSTS_
24 | #define _NSETCHOSTS_
25 | #import "EtcHostsURLProtocol.h"
26 | #endif
27 |
--------------------------------------------------------------------------------
/Example/iOS Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.mattt.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NSEtcHosts
2 |
3 | > This project was a proof-of-concept that relied on a combination of factors unique to the time of creation
4 | > that have since been remediated by, among other things,
5 | > the ubiquitous adoption of HTTPS, iOS App Transport Security, and `NSURLSession`.
6 | > Insofar as this approach should ever have been used (it shouldn't)
7 | > the aforementioned improvements to the networking stack render this project inviable.
8 | > Suffice to say, this project is no longer maintained.
9 |
10 | NSEtcHosts uses `NSURLProtocol` to intercept requests for specified host names,
11 | resolving them instead to a different IP address,
12 | similar to an [`/etc/hosts` file](http://en.wikipedia.org/wiki/Hosts_%28file%29) on a Unix system.
13 | (This does not actually affect the _actual_ hosts file used by iOS,
14 | nor does it affect routing behavior outside of the application process)
15 |
16 | ## Usage
17 |
18 | ```objective-c
19 | [NSURLProtocol registerClass:[EtcHostsURLProtocol class]];
20 | [EtcHostsURLProtocol configureHostsWithBlock:^(id configuration) {
21 | [configuration resolveHostName:@"google.com" toIPAddress:@"98.138.253.109"];
22 | }];
23 | ```
24 |
25 | ## Contact
26 |
27 | [Mattt](https://twitter.com/mattt)
28 |
29 | ## License
30 |
31 | NSEtcHosts is available under the MIT license.
32 | See the LICENSE file for more info.
33 |
--------------------------------------------------------------------------------
/Example/iOS Example/AppDelegate.h:
--------------------------------------------------------------------------------
1 | // AppDelegate.h
2 | //
3 | // Copyright (c) 2014 Mattt (https://mat.tt)
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 | #import
24 |
25 | @interface AppDelegate : UIResponder
26 |
27 | @property (strong, nonatomic) UIWindow *window;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Example/iOS Example/WebViewController.h:
--------------------------------------------------------------------------------
1 | // WebViewController.h
2 | //
3 | // Copyright (c) 2014 Mattt (https://mat.tt)
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 | #import
24 |
25 | @interface WebViewController : UIViewController
26 |
27 | @property (nonatomic, strong) IBOutlet UIWebView *webView;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Example/iOS Example/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2014 Mattt (https://mat.tt)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import "AppDelegate.h"
25 |
26 | int main(int argc, char *argv[]) {
27 | @autoreleasepool {
28 | return UIApplicationMain(argc, argv, nil,
29 | NSStringFromClass([AppDelegate class]));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/NSEtcHosts/EtcHostsURLProtocol.h:
--------------------------------------------------------------------------------
1 | // EtcHostsURLProtocol.h
2 | //
3 | // Copyright (c) 2014 Mattt (https://mat.tt)
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 | #import
24 |
25 | @protocol EtcHostsConfiguration;
26 |
27 | /**
28 |
29 | */
30 | @interface EtcHostsURLProtocol : NSURLProtocol
31 |
32 | /**
33 |
34 | */
35 | + (void)configureHostsWithBlock:(void (^)(id configuration))block;
36 |
37 | @end
38 |
39 | #pragma mark -
40 |
41 | /**
42 |
43 | */
44 | @protocol EtcHostsConfiguration
45 |
46 | /**
47 |
48 | */
49 | - (void)resolveHostName:(NSString *)hostName
50 | toIPAddress:(NSString *)IPAddress;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/Example/iOS Example/AppDelegate.m:
--------------------------------------------------------------------------------
1 | // AppDelegate.m
2 | //
3 | // Copyright (c) 2014 Mattt (https://mat.tt)
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 | #import "AppDelegate.h"
24 |
25 | #import "WebViewController.h"
26 |
27 | #import "NSEtcHosts.h"
28 |
29 | @implementation AppDelegate
30 |
31 | - (BOOL)application:(UIApplication *)application
32 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
33 | {
34 | [NSURLProtocol registerClass:[EtcHostsURLProtocol class]];
35 | [EtcHostsURLProtocol configureHostsWithBlock:^(id configuration) {
36 | [configuration resolveHostName:@"google.com" toIPAddress:@"98.138.253.109"];
37 | }];
38 |
39 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
40 | self.window.backgroundColor = [UIColor whiteColor];
41 |
42 | WebViewController *viewController = [[WebViewController alloc] init];
43 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
44 |
45 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
46 | NSString *URLString = @"http://google.com";
47 | viewController.navigationItem.prompt = URLString;
48 | [viewController.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:URLString]]];
49 | });
50 |
51 | self.window.rootViewController = navigationController;
52 |
53 | [self.window makeKeyAndVisible];
54 |
55 | return YES;
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/Example/iOS Example/WebViewController.m:
--------------------------------------------------------------------------------
1 | // WebViewController.m
2 | //
3 | // Copyright (c) 2014 Mattt (https://mat.tt)
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 | #import "WebViewController.h"
24 |
25 | @interface WebViewController ()
26 | @property (readwrite, nonatomic, strong) UIActivityIndicatorView *loadingActivityIndicatorView;
27 | @end
28 |
29 | @implementation WebViewController
30 |
31 | #pragma mark - UIViewController
32 |
33 | - (void)loadView {
34 | [super loadView];
35 |
36 | self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
37 | self.webView.delegate = self;
38 | [self.view addSubview:self.webView];
39 |
40 | self.loadingActivityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
41 | self.loadingActivityIndicatorView.hidesWhenStopped = YES;
42 | }
43 |
44 | - (void)viewDidLoad {
45 | [super viewDidLoad];
46 |
47 | self.title = NSLocalizedString(@"NSEtcHosts", nil);
48 |
49 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.loadingActivityIndicatorView];
50 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(showActionSheet:)];
51 | self.navigationItem.rightBarButtonItem.enabled = NO;
52 | }
53 |
54 | #pragma mark - IBAction
55 |
56 | - (IBAction)showActionSheet:(id)sender {
57 | [[[UIActionSheet alloc] initWithTitle:[[self.webView.request URL] absoluteString] delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) destructiveButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Open in Safari", nil), nil] showInView:self.view];
58 | }
59 |
60 | - (IBAction)openInSafari:(id)sender {
61 | [[UIApplication sharedApplication] openURL:[self.webView.request URL]];
62 | }
63 |
64 | #pragma mark - UIWebViewDelegate
65 |
66 | - (void)webViewDidStartLoad:(UIWebView *)webView {
67 | self.navigationItem.rightBarButtonItem.enabled = YES;
68 |
69 | [self.loadingActivityIndicatorView startAnimating];
70 | }
71 |
72 | - (void)webViewDidFinishLoad:(UIWebView *)webView {
73 | [self.loadingActivityIndicatorView stopAnimating];
74 | }
75 |
76 | #pragma mark - UIActionSheetDelegate
77 |
78 | - (void)actionSheet:(UIActionSheet *)actionSheet
79 | clickedButtonAtIndex:(NSInteger)buttonIndex
80 | {
81 | if (buttonIndex != actionSheet.cancelButtonIndex) {
82 | [self openInSafari:actionSheet];
83 | }
84 | }
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/NSEtcHosts/EtcHostsURLProtocol.m:
--------------------------------------------------------------------------------
1 | // EtcHostsURLProtocol.m
2 | //
3 | // Copyright (c) 2014 Mattt (https://mat.tt)
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 | #import "EtcHostsURLProtocol.h"
24 |
25 | static NSString * const EtcHostModifiedPropertyKey = @"EtcHostModifiedProperty";
26 |
27 | @interface EtcHostsConfiguration : NSObject
28 | - (NSString *)IPAddressForHostName:(NSString *)hostName;
29 | @end
30 |
31 | #pragma mark -
32 |
33 | @interface EtcHostsURLProtocol ()
34 | @property (readwrite, nonatomic, strong) NSURLConnection *connection;
35 | @end
36 |
37 | @implementation EtcHostsURLProtocol
38 |
39 | + (EtcHostsConfiguration *)sharedConfiguration {
40 | static EtcHostsConfiguration * _sharedConfiguration = nil;
41 | static dispatch_once_t onceToken;
42 | dispatch_once(&onceToken, ^{
43 | _sharedConfiguration = [[EtcHostsConfiguration alloc] init];
44 | });
45 |
46 | return _sharedConfiguration;
47 | }
48 |
49 | + (void)configureHostsWithBlock:(void (^)(id configuration))block {
50 | if (block) {
51 | block([self sharedConfiguration]);
52 | }
53 | }
54 |
55 | #pragma mark - NSURLProtocol
56 |
57 | + (BOOL)canInitWithRequest:(NSURLRequest *)request {
58 | return [[self sharedConfiguration] IPAddressForHostName:[[request URL] host]] && ([[[request URL] scheme] caseInsensitiveCompare:@"http"] == NSOrderedSame || [[[request URL] scheme] caseInsensitiveCompare:@"https"] == NSOrderedSame);
59 | }
60 |
61 | + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
62 | NSMutableURLRequest *mutableRequest = [request mutableCopy];
63 |
64 | NSURLComponents *URLComponents = [NSURLComponents componentsWithString:[[mutableRequest URL] absoluteString]];
65 | URLComponents.scheme = @"http";
66 | URLComponents.host = [[[self class] sharedConfiguration] IPAddressForHostName:URLComponents.host];
67 |
68 | mutableRequest.URL = [URLComponents URL];
69 |
70 | [NSURLProtocol setProperty:@(YES) forKey:EtcHostModifiedPropertyKey inRequest:mutableRequest];
71 |
72 | return mutableRequest;
73 | }
74 |
75 | - (void)startLoading {
76 | self.connection = [[NSURLConnection alloc] initWithRequest:[[self class] canonicalRequestForRequest:self.request] delegate:self startImmediately:YES];
77 | }
78 |
79 | - (void)stopLoading {
80 | [self.connection cancel];
81 | }
82 |
83 | #pragma mark - NSURLConnectionDelegate
84 |
85 | - (void)connection:(NSURLConnection *)connection
86 | didFailWithError:(NSError *)error
87 | {
88 | [[self client] URLProtocol:self didFailWithError:error];
89 | }
90 |
91 | - (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection {
92 | return YES;
93 | }
94 |
95 | - (void)connection:(NSURLConnection *)connection
96 | didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
97 | [[self client] URLProtocol:self didReceiveAuthenticationChallenge:challenge];
98 | }
99 |
100 | - (void)connection:(NSURLConnection *)connection
101 | didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
102 | [[self client] URLProtocol:self didCancelAuthenticationChallenge:challenge];
103 | }
104 |
105 | #pragma mark - NSURLConnectionDataDelegate
106 |
107 | - (void)connection:(NSURLConnection *)connection
108 | didReceiveResponse:(NSURLResponse *)response
109 | {
110 | [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:[[self request] cachePolicy]];
111 | }
112 |
113 | - (void)connection:(NSURLConnection *)connection
114 | didReceiveData:(NSData *)data
115 | {
116 | [[self client] URLProtocol:self didLoadData:data];
117 | }
118 |
119 | - (NSCachedURLResponse *)connection:(NSURLConnection *)connection
120 | willCacheResponse:(NSCachedURLResponse *)cachedResponse
121 | {
122 | return cachedResponse;
123 | }
124 |
125 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
126 | [[self client] URLProtocolDidFinishLoading:self];
127 | }
128 |
129 | @end
130 |
131 | #pragma mark -
132 |
133 | @interface EtcHostsConfiguration ()
134 | @property (readwrite, nonatomic, strong) NSMutableDictionary *mutableIPAddressesByHostName;
135 | @end
136 |
137 | @implementation EtcHostsConfiguration
138 |
139 | - (instancetype)init {
140 | self = [super init];
141 | if (!self) {
142 | return nil;
143 | }
144 |
145 | self.mutableIPAddressesByHostName = [[NSMutableDictionary alloc] init];
146 |
147 | return self;
148 | }
149 |
150 | - (NSString *)IPAddressForHostName:(NSString *)hostName {
151 | return self.mutableIPAddressesByHostName[hostName];
152 | }
153 |
154 | #pragma mark - EtcHostsConfiguration
155 |
156 | - (void)resolveHostName:(NSString *)hostName
157 | toIPAddress:(NSString *)IPAddress
158 | {
159 | NSParameterAssert(hostName);
160 | NSParameterAssert(IPAddress);
161 |
162 | self.mutableIPAddressesByHostName[[hostName lowercaseString]] = IPAddress;
163 | }
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/Example/iOS Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | F8BC187118FE5C5C00684397 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8BC187018FE5C5C00684397 /* Foundation.framework */; };
11 | F8BC187318FE5C5C00684397 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8BC187218FE5C5C00684397 /* CoreGraphics.framework */; };
12 | F8BC187518FE5C5C00684397 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8BC187418FE5C5C00684397 /* UIKit.framework */; };
13 | F8BC187B18FE5C5C00684397 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F8BC187918FE5C5C00684397 /* InfoPlist.strings */; };
14 | F8BC187D18FE5C5C00684397 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F8BC187C18FE5C5C00684397 /* main.m */; };
15 | F8BC188118FE5C5C00684397 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F8BC188018FE5C5C00684397 /* AppDelegate.m */; };
16 | F8BC188A18FE5C5C00684397 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8BC188918FE5C5C00684397 /* XCTest.framework */; };
17 | F8BC188B18FE5C5C00684397 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8BC187018FE5C5C00684397 /* Foundation.framework */; };
18 | F8BC188C18FE5C5C00684397 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8BC187418FE5C5C00684397 /* UIKit.framework */; };
19 | F8BC18A218FE5D3000684397 /* EtcHostsURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = F8BC18A118FE5D3000684397 /* EtcHostsURLProtocol.m */; };
20 | F8BC18A618FE67F200684397 /* WebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F8BC18A518FE67F200684397 /* WebViewController.m */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXContainerItemProxy section */
24 | F8BC188D18FE5C5C00684397 /* PBXContainerItemProxy */ = {
25 | isa = PBXContainerItemProxy;
26 | containerPortal = F8BC186518FE5C5B00684397 /* Project object */;
27 | proxyType = 1;
28 | remoteGlobalIDString = F8BC186C18FE5C5C00684397;
29 | remoteInfo = NSEtcHosts;
30 | };
31 | /* End PBXContainerItemProxy section */
32 |
33 | /* Begin PBXFileReference section */
34 | F8BC186D18FE5C5C00684397 /* NSEtcHosts.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NSEtcHosts.app; sourceTree = BUILT_PRODUCTS_DIR; };
35 | F8BC187018FE5C5C00684397 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
36 | F8BC187218FE5C5C00684397 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
37 | F8BC187418FE5C5C00684397 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
38 | F8BC187818FE5C5C00684397 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
39 | F8BC187A18FE5C5C00684397 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
40 | F8BC187C18FE5C5C00684397 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
41 | F8BC187E18FE5C5C00684397 /* Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = ""; };
42 | F8BC187F18FE5C5C00684397 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
43 | F8BC188018FE5C5C00684397 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
44 | F8BC188818FE5C5C00684397 /* NSEtcHostsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NSEtcHostsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
45 | F8BC188918FE5C5C00684397 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
46 | F8BC18A018FE5D3000684397 /* EtcHostsURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EtcHostsURLProtocol.h; path = ../NSEtcHosts/EtcHostsURLProtocol.h; sourceTree = ""; };
47 | F8BC18A118FE5D3000684397 /* EtcHostsURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EtcHostsURLProtocol.m; path = ../NSEtcHosts/EtcHostsURLProtocol.m; sourceTree = ""; };
48 | F8BC18A418FE67F200684397 /* WebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewController.h; sourceTree = ""; };
49 | F8BC18A518FE67F200684397 /* WebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewController.m; sourceTree = ""; };
50 | F8BC18A718FE6FE300684397 /* NSEtcHosts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSEtcHosts.h; path = ../NSEtcHosts/NSEtcHosts.h; sourceTree = ""; };
51 | /* End PBXFileReference section */
52 |
53 | /* Begin PBXFrameworksBuildPhase section */
54 | F8BC186A18FE5C5C00684397 /* Frameworks */ = {
55 | isa = PBXFrameworksBuildPhase;
56 | buildActionMask = 2147483647;
57 | files = (
58 | F8BC187318FE5C5C00684397 /* CoreGraphics.framework in Frameworks */,
59 | F8BC187518FE5C5C00684397 /* UIKit.framework in Frameworks */,
60 | F8BC187118FE5C5C00684397 /* Foundation.framework in Frameworks */,
61 | );
62 | runOnlyForDeploymentPostprocessing = 0;
63 | };
64 | F8BC188518FE5C5C00684397 /* Frameworks */ = {
65 | isa = PBXFrameworksBuildPhase;
66 | buildActionMask = 2147483647;
67 | files = (
68 | F8BC188A18FE5C5C00684397 /* XCTest.framework in Frameworks */,
69 | F8BC188C18FE5C5C00684397 /* UIKit.framework in Frameworks */,
70 | F8BC188B18FE5C5C00684397 /* Foundation.framework in Frameworks */,
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | /* End PBXFrameworksBuildPhase section */
75 |
76 | /* Begin PBXGroup section */
77 | F8BC186418FE5C5B00684397 = {
78 | isa = PBXGroup;
79 | children = (
80 | F8BC187618FE5C5C00684397 /* NSEtcHosts */,
81 | F8BC186F18FE5C5C00684397 /* Frameworks */,
82 | F8BC186E18FE5C5C00684397 /* Products */,
83 | F8BC189F18FE5CF400684397 /* Vendor */,
84 | );
85 | sourceTree = "";
86 | };
87 | F8BC186E18FE5C5C00684397 /* Products */ = {
88 | isa = PBXGroup;
89 | children = (
90 | F8BC186D18FE5C5C00684397 /* NSEtcHosts.app */,
91 | F8BC188818FE5C5C00684397 /* NSEtcHostsTests.xctest */,
92 | );
93 | name = Products;
94 | sourceTree = "";
95 | };
96 | F8BC186F18FE5C5C00684397 /* Frameworks */ = {
97 | isa = PBXGroup;
98 | children = (
99 | F8BC187018FE5C5C00684397 /* Foundation.framework */,
100 | F8BC187218FE5C5C00684397 /* CoreGraphics.framework */,
101 | F8BC187418FE5C5C00684397 /* UIKit.framework */,
102 | F8BC188918FE5C5C00684397 /* XCTest.framework */,
103 | );
104 | name = Frameworks;
105 | sourceTree = "";
106 | };
107 | F8BC187618FE5C5C00684397 /* NSEtcHosts */ = {
108 | isa = PBXGroup;
109 | children = (
110 | F8BC187F18FE5C5C00684397 /* AppDelegate.h */,
111 | F8BC188018FE5C5C00684397 /* AppDelegate.m */,
112 | F8BC18A418FE67F200684397 /* WebViewController.h */,
113 | F8BC18A518FE67F200684397 /* WebViewController.m */,
114 | F8BC187718FE5C5C00684397 /* Supporting Files */,
115 | );
116 | name = NSEtcHosts;
117 | path = "iOS Example";
118 | sourceTree = "";
119 | };
120 | F8BC187718FE5C5C00684397 /* Supporting Files */ = {
121 | isa = PBXGroup;
122 | children = (
123 | F8BC187818FE5C5C00684397 /* Info.plist */,
124 | F8BC187918FE5C5C00684397 /* InfoPlist.strings */,
125 | F8BC187C18FE5C5C00684397 /* main.m */,
126 | F8BC187E18FE5C5C00684397 /* Prefix.pch */,
127 | );
128 | name = "Supporting Files";
129 | sourceTree = "";
130 | };
131 | F8BC189F18FE5CF400684397 /* Vendor */ = {
132 | isa = PBXGroup;
133 | children = (
134 | F8BC18A318FE5D3500684397 /* NSEtcHosts */,
135 | );
136 | name = Vendor;
137 | sourceTree = "";
138 | };
139 | F8BC18A318FE5D3500684397 /* NSEtcHosts */ = {
140 | isa = PBXGroup;
141 | children = (
142 | F8BC18A718FE6FE300684397 /* NSEtcHosts.h */,
143 | F8BC18A018FE5D3000684397 /* EtcHostsURLProtocol.h */,
144 | F8BC18A118FE5D3000684397 /* EtcHostsURLProtocol.m */,
145 | );
146 | name = NSEtcHosts;
147 | sourceTree = "";
148 | };
149 | /* End PBXGroup section */
150 |
151 | /* Begin PBXNativeTarget section */
152 | F8BC186C18FE5C5C00684397 /* NSEtcHosts */ = {
153 | isa = PBXNativeTarget;
154 | buildConfigurationList = F8BC189918FE5C5C00684397 /* Build configuration list for PBXNativeTarget "NSEtcHosts" */;
155 | buildPhases = (
156 | F8BC186918FE5C5C00684397 /* Sources */,
157 | F8BC186A18FE5C5C00684397 /* Frameworks */,
158 | F8BC186B18FE5C5C00684397 /* Resources */,
159 | );
160 | buildRules = (
161 | );
162 | dependencies = (
163 | );
164 | name = NSEtcHosts;
165 | productName = NSEtcHosts;
166 | productReference = F8BC186D18FE5C5C00684397 /* NSEtcHosts.app */;
167 | productType = "com.apple.product-type.application";
168 | };
169 | F8BC188718FE5C5C00684397 /* NSEtcHostsTests */ = {
170 | isa = PBXNativeTarget;
171 | buildConfigurationList = F8BC189C18FE5C5C00684397 /* Build configuration list for PBXNativeTarget "NSEtcHostsTests" */;
172 | buildPhases = (
173 | F8BC188418FE5C5C00684397 /* Sources */,
174 | F8BC188518FE5C5C00684397 /* Frameworks */,
175 | F8BC188618FE5C5C00684397 /* Resources */,
176 | );
177 | buildRules = (
178 | );
179 | dependencies = (
180 | F8BC188E18FE5C5C00684397 /* PBXTargetDependency */,
181 | );
182 | name = NSEtcHostsTests;
183 | productName = NSEtcHostsTests;
184 | productReference = F8BC188818FE5C5C00684397 /* NSEtcHostsTests.xctest */;
185 | productType = "com.apple.product-type.bundle.unit-test";
186 | };
187 | /* End PBXNativeTarget section */
188 |
189 | /* Begin PBXProject section */
190 | F8BC186518FE5C5B00684397 /* Project object */ = {
191 | isa = PBXProject;
192 | attributes = {
193 | LastUpgradeCheck = 0510;
194 | ORGANIZATIONNAME = "Mattt";
195 | TargetAttributes = {
196 | F8BC188718FE5C5C00684397 = {
197 | TestTargetID = F8BC186C18FE5C5C00684397;
198 | };
199 | };
200 | };
201 | buildConfigurationList = F8BC186818FE5C5B00684397 /* Build configuration list for PBXProject "iOS Example" */;
202 | compatibilityVersion = "Xcode 3.2";
203 | developmentRegion = English;
204 | hasScannedForEncodings = 0;
205 | knownRegions = (
206 | English,
207 | en,
208 | );
209 | mainGroup = F8BC186418FE5C5B00684397;
210 | productRefGroup = F8BC186E18FE5C5C00684397 /* Products */;
211 | projectDirPath = "";
212 | projectRoot = "";
213 | targets = (
214 | F8BC186C18FE5C5C00684397 /* NSEtcHosts */,
215 | F8BC188718FE5C5C00684397 /* NSEtcHostsTests */,
216 | );
217 | };
218 | /* End PBXProject section */
219 |
220 | /* Begin PBXResourcesBuildPhase section */
221 | F8BC186B18FE5C5C00684397 /* Resources */ = {
222 | isa = PBXResourcesBuildPhase;
223 | buildActionMask = 2147483647;
224 | files = (
225 | F8BC187B18FE5C5C00684397 /* InfoPlist.strings in Resources */,
226 | );
227 | runOnlyForDeploymentPostprocessing = 0;
228 | };
229 | F8BC188618FE5C5C00684397 /* Resources */ = {
230 | isa = PBXResourcesBuildPhase;
231 | buildActionMask = 2147483647;
232 | files = (
233 | );
234 | runOnlyForDeploymentPostprocessing = 0;
235 | };
236 | /* End PBXResourcesBuildPhase section */
237 |
238 | /* Begin PBXSourcesBuildPhase section */
239 | F8BC186918FE5C5C00684397 /* Sources */ = {
240 | isa = PBXSourcesBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | F8BC18A218FE5D3000684397 /* EtcHostsURLProtocol.m in Sources */,
244 | F8BC188118FE5C5C00684397 /* AppDelegate.m in Sources */,
245 | F8BC187D18FE5C5C00684397 /* main.m in Sources */,
246 | F8BC18A618FE67F200684397 /* WebViewController.m in Sources */,
247 | );
248 | runOnlyForDeploymentPostprocessing = 0;
249 | };
250 | F8BC188418FE5C5C00684397 /* Sources */ = {
251 | isa = PBXSourcesBuildPhase;
252 | buildActionMask = 2147483647;
253 | files = (
254 | );
255 | runOnlyForDeploymentPostprocessing = 0;
256 | };
257 | /* End PBXSourcesBuildPhase section */
258 |
259 | /* Begin PBXTargetDependency section */
260 | F8BC188E18FE5C5C00684397 /* PBXTargetDependency */ = {
261 | isa = PBXTargetDependency;
262 | target = F8BC186C18FE5C5C00684397 /* NSEtcHosts */;
263 | targetProxy = F8BC188D18FE5C5C00684397 /* PBXContainerItemProxy */;
264 | };
265 | /* End PBXTargetDependency section */
266 |
267 | /* Begin PBXVariantGroup section */
268 | F8BC187918FE5C5C00684397 /* InfoPlist.strings */ = {
269 | isa = PBXVariantGroup;
270 | children = (
271 | F8BC187A18FE5C5C00684397 /* en */,
272 | );
273 | name = InfoPlist.strings;
274 | sourceTree = "";
275 | };
276 | /* End PBXVariantGroup section */
277 |
278 | /* Begin XCBuildConfiguration section */
279 | F8BC189718FE5C5C00684397 /* Debug */ = {
280 | isa = XCBuildConfiguration;
281 | buildSettings = {
282 | ALWAYS_SEARCH_USER_PATHS = NO;
283 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
284 | CLANG_CXX_LIBRARY = "libc++";
285 | CLANG_ENABLE_MODULES = YES;
286 | CLANG_ENABLE_OBJC_ARC = YES;
287 | CLANG_WARN_BOOL_CONVERSION = YES;
288 | CLANG_WARN_CONSTANT_CONVERSION = YES;
289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
290 | CLANG_WARN_EMPTY_BODY = YES;
291 | CLANG_WARN_ENUM_CONVERSION = YES;
292 | CLANG_WARN_INT_CONVERSION = YES;
293 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
294 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
295 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
296 | COPY_PHASE_STRIP = NO;
297 | GCC_C_LANGUAGE_STANDARD = gnu99;
298 | GCC_DYNAMIC_NO_PIC = NO;
299 | GCC_OPTIMIZATION_LEVEL = 0;
300 | GCC_PREPROCESSOR_DEFINITIONS = (
301 | "DEBUG=1",
302 | "$(inherited)",
303 | );
304 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
305 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
306 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
307 | GCC_WARN_UNDECLARED_SELECTOR = YES;
308 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
309 | GCC_WARN_UNUSED_FUNCTION = YES;
310 | GCC_WARN_UNUSED_VARIABLE = YES;
311 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
312 | ONLY_ACTIVE_ARCH = YES;
313 | SDKROOT = iphoneos;
314 | };
315 | name = Debug;
316 | };
317 | F8BC189818FE5C5C00684397 /* Release */ = {
318 | isa = XCBuildConfiguration;
319 | buildSettings = {
320 | ALWAYS_SEARCH_USER_PATHS = NO;
321 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
322 | CLANG_CXX_LIBRARY = "libc++";
323 | CLANG_ENABLE_MODULES = YES;
324 | CLANG_ENABLE_OBJC_ARC = YES;
325 | CLANG_WARN_BOOL_CONVERSION = YES;
326 | CLANG_WARN_CONSTANT_CONVERSION = YES;
327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
328 | CLANG_WARN_EMPTY_BODY = YES;
329 | CLANG_WARN_ENUM_CONVERSION = YES;
330 | CLANG_WARN_INT_CONVERSION = YES;
331 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
334 | COPY_PHASE_STRIP = YES;
335 | ENABLE_NS_ASSERTIONS = NO;
336 | GCC_C_LANGUAGE_STANDARD = gnu99;
337 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
338 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
339 | GCC_WARN_UNDECLARED_SELECTOR = YES;
340 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
341 | GCC_WARN_UNUSED_FUNCTION = YES;
342 | GCC_WARN_UNUSED_VARIABLE = YES;
343 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
344 | SDKROOT = iphoneos;
345 | VALIDATE_PRODUCT = YES;
346 | };
347 | name = Release;
348 | };
349 | F8BC189A18FE5C5C00684397 /* Debug */ = {
350 | isa = XCBuildConfiguration;
351 | buildSettings = {
352 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
353 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
354 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
355 | GCC_PREFIX_HEADER = "iOS Example/Prefix.pch";
356 | INFOPLIST_FILE = "$(SRCROOT)/iOS Example/Info.plist";
357 | PRODUCT_NAME = "$(TARGET_NAME)";
358 | WRAPPER_EXTENSION = app;
359 | };
360 | name = Debug;
361 | };
362 | F8BC189B18FE5C5C00684397 /* Release */ = {
363 | isa = XCBuildConfiguration;
364 | buildSettings = {
365 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
366 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
367 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
368 | GCC_PREFIX_HEADER = "iOS Example/Prefix.pch";
369 | INFOPLIST_FILE = "$(SRCROOT)/iOS Example/Info.plist";
370 | PRODUCT_NAME = "$(TARGET_NAME)";
371 | WRAPPER_EXTENSION = app;
372 | };
373 | name = Release;
374 | };
375 | F8BC189D18FE5C5C00684397 /* Debug */ = {
376 | isa = XCBuildConfiguration;
377 | buildSettings = {
378 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NSEtcHosts.app/NSEtcHosts";
379 | FRAMEWORK_SEARCH_PATHS = (
380 | "$(SDKROOT)/Developer/Library/Frameworks",
381 | "$(inherited)",
382 | "$(DEVELOPER_FRAMEWORKS_DIR)",
383 | );
384 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
385 | GCC_PREFIX_HEADER = "NSEtcHosts/NSEtcHosts-Prefix.pch";
386 | GCC_PREPROCESSOR_DEFINITIONS = (
387 | "DEBUG=1",
388 | "$(inherited)",
389 | );
390 | INFOPLIST_FILE = "NSEtcHostsTests/NSEtcHostsTests-Info.plist";
391 | PRODUCT_NAME = "$(TARGET_NAME)";
392 | TEST_HOST = "$(BUNDLE_LOADER)";
393 | WRAPPER_EXTENSION = xctest;
394 | };
395 | name = Debug;
396 | };
397 | F8BC189E18FE5C5C00684397 /* Release */ = {
398 | isa = XCBuildConfiguration;
399 | buildSettings = {
400 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NSEtcHosts.app/NSEtcHosts";
401 | FRAMEWORK_SEARCH_PATHS = (
402 | "$(SDKROOT)/Developer/Library/Frameworks",
403 | "$(inherited)",
404 | "$(DEVELOPER_FRAMEWORKS_DIR)",
405 | );
406 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
407 | GCC_PREFIX_HEADER = "NSEtcHosts/NSEtcHosts-Prefix.pch";
408 | INFOPLIST_FILE = "NSEtcHostsTests/NSEtcHostsTests-Info.plist";
409 | PRODUCT_NAME = "$(TARGET_NAME)";
410 | TEST_HOST = "$(BUNDLE_LOADER)";
411 | WRAPPER_EXTENSION = xctest;
412 | };
413 | name = Release;
414 | };
415 | /* End XCBuildConfiguration section */
416 |
417 | /* Begin XCConfigurationList section */
418 | F8BC186818FE5C5B00684397 /* Build configuration list for PBXProject "iOS Example" */ = {
419 | isa = XCConfigurationList;
420 | buildConfigurations = (
421 | F8BC189718FE5C5C00684397 /* Debug */,
422 | F8BC189818FE5C5C00684397 /* Release */,
423 | );
424 | defaultConfigurationIsVisible = 0;
425 | defaultConfigurationName = Release;
426 | };
427 | F8BC189918FE5C5C00684397 /* Build configuration list for PBXNativeTarget "NSEtcHosts" */ = {
428 | isa = XCConfigurationList;
429 | buildConfigurations = (
430 | F8BC189A18FE5C5C00684397 /* Debug */,
431 | F8BC189B18FE5C5C00684397 /* Release */,
432 | );
433 | defaultConfigurationIsVisible = 0;
434 | defaultConfigurationName = Release;
435 | };
436 | F8BC189C18FE5C5C00684397 /* Build configuration list for PBXNativeTarget "NSEtcHostsTests" */ = {
437 | isa = XCConfigurationList;
438 | buildConfigurations = (
439 | F8BC189D18FE5C5C00684397 /* Debug */,
440 | F8BC189E18FE5C5C00684397 /* Release */,
441 | );
442 | defaultConfigurationIsVisible = 0;
443 | defaultConfigurationName = Release;
444 | };
445 | /* End XCConfigurationList section */
446 | };
447 | rootObject = F8BC186518FE5C5B00684397 /* Project object */;
448 | }
449 |
--------------------------------------------------------------------------------