mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-06 13:47:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// NSDictionary+Parsing.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 10/28/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSDictionary (Parsing)
|
||||
|
||||
- (BOOL) boolValueForKey:(NSString*)key;
|
||||
- (BOOL) boolValueForKey:(NSString*)key withDefault:(BOOL)defaultValue;
|
||||
|
||||
-(NSInteger) intValueForKey:(NSString*)key;
|
||||
-(NSInteger) intValueForKey:(NSString*)key withDefault:(NSInteger)defaultValue;
|
||||
|
||||
-(NSUInteger) unsignedValueForKey:(NSString*)key;
|
||||
-(NSUInteger) unsignedValueForKey:(NSString*)key withDefault:(NSUInteger)defaultValue;
|
||||
|
||||
-(double) doubleValueForKey:(NSString*)key;
|
||||
-(double) doubleValueForKey:(NSString*)key withDefault:(double)defaultValue;
|
||||
|
||||
-(NSNumber*) numberForKey:(NSString*)key;
|
||||
-(NSNumber*) numberForKey:(NSString*)key withDefault:(NSNumber*)defaultValue;
|
||||
|
||||
-(NSString*) stringForKey:(NSString*)key;
|
||||
-(NSString*) stringForKey:(NSString*)key withDefault:(NSString*)defaultValue;
|
||||
|
||||
-(NSArray*) arrayForKey:(NSString*)key;
|
||||
-(NSArray*) arrayForKey:(NSString*)key withDefault:(NSArray*)defaultValue;
|
||||
|
||||
-(NSDictionary*) dictionaryForKey:(NSString*)key;
|
||||
-(NSDictionary*) dictionaryForKey:(NSString*)key withDefault:(NSDictionary*)defaultValue;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// NSDictionary+Parsing.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 10/28/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSDictionary+Parsing.h"
|
||||
|
||||
@implementation NSDictionary (Parsing)
|
||||
|
||||
- (BOOL) boolValueForKey:(NSString*)key
|
||||
{
|
||||
return [self boolValueForKey:key withDefault:NO];
|
||||
}
|
||||
|
||||
- (BOOL) boolValueForKey:(NSString*)key withDefault:(BOOL)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil && [object isKindOfClass:[NSNumber class]])
|
||||
return [object boolValue];
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
-(NSInteger) intValueForKey:(NSString*)key
|
||||
{
|
||||
return [self intValueForKey:key withDefault:0];
|
||||
}
|
||||
|
||||
-(NSInteger) intValueForKey:(NSString*)key withDefault:(NSInteger)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil && [object isKindOfClass:[NSNumber class]])
|
||||
return [object integerValue];
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
-(NSUInteger) unsignedValueForKey:(NSString*)key
|
||||
{
|
||||
return [self unsignedValueForKey:key withDefault:0];
|
||||
}
|
||||
|
||||
-(NSUInteger) unsignedValueForKey:(NSString*)key withDefault:(NSUInteger)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil && [object isKindOfClass:[NSNumber class]])
|
||||
return [object unsignedIntegerValue];
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
-(double) doubleValueForKey:(NSString*)key
|
||||
{
|
||||
return [self doubleValueForKey:key withDefault:0.0];
|
||||
}
|
||||
|
||||
-(double) doubleValueForKey:(NSString*)key withDefault:(double)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil && [object isKindOfClass:[NSNumber class]])
|
||||
return [object doubleValue];
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
-(NSNumber*) numberForKey:(NSString*)key
|
||||
{
|
||||
return [self numberForKey:key withDefault:[NSNumber numberWithInt:0]];
|
||||
}
|
||||
|
||||
-(NSNumber*) numberForKey:(NSString*)key withDefault:(NSNumber*)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil && [object isKindOfClass:[NSNumber class]])
|
||||
return object;
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
-(NSString*) stringForKey:(NSString*)key
|
||||
{
|
||||
return [self stringForKey:key withDefault:@""];
|
||||
}
|
||||
|
||||
-(NSString*) stringForKey:(NSString*)key withDefault:(NSString*)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil)
|
||||
{
|
||||
if( [object isKindOfClass:[NSString class]] )
|
||||
return object;
|
||||
else if( [object isKindOfClass:[NSNumber class]] )
|
||||
return [object stringValue];
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
-(NSArray*) arrayForKey:(NSString*)key
|
||||
{
|
||||
return [self arrayForKey:key withDefault:[NSArray array]];
|
||||
}
|
||||
|
||||
-(NSArray*) arrayForKey:(NSString*)key withDefault:(NSArray*)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil && [object isKindOfClass:[NSArray class]])
|
||||
return object;
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
-(NSDictionary*) dictionaryForKey:(NSString*)key
|
||||
{
|
||||
return [self dictionaryForKey:key withDefault:[NSDictionary dictionary]];
|
||||
}
|
||||
|
||||
-(NSDictionary*) dictionaryForKey:(NSString*)key withDefault:(NSDictionary*)defaultValue
|
||||
{
|
||||
id object = [self objectForKey:key];
|
||||
if(object != nil && [object isKindOfClass:[NSDictionary class]])
|
||||
return object;
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// NSString+stripHtml.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 7/2/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSString (stripHtml)
|
||||
|
||||
- (NSString*)stringByStrippingHTML;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// NSString+stripHtml.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 7/2/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSString+stripHtml.h"
|
||||
|
||||
@interface NSString_stripHtml_XMLParsee : NSObject<NSXMLParserDelegate>
|
||||
{
|
||||
NSMutableArray* strings;
|
||||
}
|
||||
- (NSString*)getCharsFound;
|
||||
@end
|
||||
|
||||
@implementation NSString_stripHtml_XMLParsee
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if((self = [super init]))
|
||||
{
|
||||
strings = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)parser:(NSXMLParser*)parser foundCharacters:(NSString*)string
|
||||
{
|
||||
[strings addObject:string];
|
||||
}
|
||||
|
||||
- (NSString*)getCharsFound
|
||||
{
|
||||
return [strings componentsJoinedByString:@""];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSString (stripHtml)
|
||||
|
||||
- (NSString*)stringByStrippingHTML
|
||||
{
|
||||
// take this string obj and wrap it in a root element to ensure only a single root element exists
|
||||
NSString* string = [NSString stringWithFormat:@"<root>%@</root>", self];
|
||||
|
||||
// add the string to the xml parser
|
||||
NSStringEncoding encoding = string.fastestEncoding;
|
||||
NSData* data = [string dataUsingEncoding:encoding];
|
||||
NSXMLParser* parser = [[NSXMLParser alloc] initWithData:data];
|
||||
|
||||
// parse the content keeping track of any chars found outside tags (this will be the stripped content)
|
||||
NSString_stripHtml_XMLParsee* parsee = [[NSString_stripHtml_XMLParsee alloc] init];
|
||||
parser.delegate = parsee;
|
||||
[parser parse];
|
||||
|
||||
// any chars found while parsing are the stripped content
|
||||
NSString* strippedString = [parsee getCharsFound];
|
||||
|
||||
// get the raw text out of the parsee after parsing, and return it
|
||||
return strippedString;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// NSTimer+Blocks.h
|
||||
//
|
||||
// Created by Jiva DeVoe on 1/14/11.
|
||||
// Copyright 2011 Random Ideas, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSTimer (Blocks)
|
||||
+(id)scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats;
|
||||
+(id)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats;
|
||||
@end
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// NSTimer+Blocks.m
|
||||
//
|
||||
// Created by Jiva DeVoe on 1/14/11.
|
||||
// Copyright 2011 Random Ideas, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSTimer+Blocks.h"
|
||||
|
||||
@implementation NSTimer (Blocks)
|
||||
|
||||
+(id)scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats
|
||||
{
|
||||
void (^block)() = [inBlock copy];
|
||||
id ret = [self scheduledTimerWithTimeInterval:inTimeInterval target:self selector:@selector(jdExecuteSimpleBlock:) userInfo:block repeats:inRepeats];
|
||||
return ret;
|
||||
}
|
||||
|
||||
+(id)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats
|
||||
{
|
||||
void (^block)() = [inBlock copy];
|
||||
id ret = [self timerWithTimeInterval:inTimeInterval target:self selector:@selector(jdExecuteSimpleBlock:) userInfo:block repeats:inRepeats];
|
||||
return ret;
|
||||
}
|
||||
|
||||
+(void)jdExecuteSimpleBlock:(NSTimer *)inTimer;
|
||||
{
|
||||
if([inTimer userInfo])
|
||||
{
|
||||
void (^block)() = (void (^)())[inTimer userInfo];
|
||||
block();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// UIAlertView+NSCookbook.h
|
||||
// SimpleAlertViewSampleApp
|
||||
//
|
||||
// Copyright (c) 2013 NSCookbook. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIAlertView (Blocks)
|
||||
|
||||
- (void)showWithCompletion:(void(^)(UIAlertView *alertView, NSInteger buttonIndex))completion;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// UIAlertView+NSCookbook.m
|
||||
// SimpleAlertViewSampleApp
|
||||
//
|
||||
// Copyright (c) 2013 NSCookbook. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import "UIAlertView+Blocks.h"
|
||||
|
||||
@interface NSCBAlertWrapper : NSObject <UIAlertViewDelegate>
|
||||
|
||||
@property (copy) void(^completionBlock)(UIAlertView *alertView, NSInteger buttonIndex);
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSCBAlertWrapper
|
||||
|
||||
#pragma mark - UIAlertViewDelegate
|
||||
|
||||
// Called when a button is clicked. The view will be automatically dismissed after this call returns
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (self.completionBlock)
|
||||
self.completionBlock(alertView, buttonIndex);
|
||||
}
|
||||
|
||||
// Called when we cancel a view (eg. the user clicks the Home button). This is not called when the user clicks the cancel button.
|
||||
// If not defined in the delegate, we simulate a click in the cancel button
|
||||
- (void)alertViewCancel:(UIAlertView *)alertView
|
||||
{
|
||||
// Just simulate a cancel button click
|
||||
if (self.completionBlock)
|
||||
self.completionBlock(alertView, alertView.cancelButtonIndex);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static const char kNSCBAlertWrapper;
|
||||
@implementation UIAlertView (Blocks)
|
||||
|
||||
#pragma mark - Class Public
|
||||
|
||||
- (void)showWithCompletion:(void(^)(UIAlertView *alertView, NSInteger buttonIndex))completion
|
||||
{
|
||||
NSCBAlertWrapper *alertWrapper = [[NSCBAlertWrapper alloc] init];
|
||||
alertWrapper.completionBlock = completion;
|
||||
self.delegate = alertWrapper;
|
||||
|
||||
// Set the wrapper as an associated object
|
||||
objc_setAssociatedObject(self, &kNSCBAlertWrapper, alertWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
|
||||
// Show the alert as normal
|
||||
[self show];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// UIButton+Extensions.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/4/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIButton (Extensions)
|
||||
|
||||
@property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;
|
||||
|
||||
- (void)setColor:(UIColor *)color forState:(UIControlState)state;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// UIButton+Extensions.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/4/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIButton+Extensions.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation UIButton (Extensions)
|
||||
|
||||
@dynamic hitTestEdgeInsets;
|
||||
|
||||
static const NSString *KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets";
|
||||
|
||||
-(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets {
|
||||
NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)];
|
||||
objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
-(UIEdgeInsets)hitTestEdgeInsets {
|
||||
NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS);
|
||||
if(value) {
|
||||
UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets;
|
||||
}else {
|
||||
return UIEdgeInsetsZero;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) {
|
||||
return [super pointInside:point withEvent:event];
|
||||
}
|
||||
|
||||
CGRect relativeFrame = self.bounds;
|
||||
CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);
|
||||
|
||||
return CGRectContainsPoint(hitFrame, point);
|
||||
}
|
||||
|
||||
- (void)setColor:(UIColor *)color forState:(UIControlState)state
|
||||
{
|
||||
UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
|
||||
colorView.backgroundColor = color;
|
||||
|
||||
UIGraphicsBeginImageContext(colorView.bounds.size);
|
||||
[colorView.layer renderInContext:UIGraphicsGetCurrentContext()];
|
||||
|
||||
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
[self setBackgroundImage:colorImage forState:state];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// UIImage+Utils.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Christian Hresko on 5/30/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIImage (Utils)
|
||||
|
||||
- (UIImage *)imageWithRoundedCornersSize:(float)cornerRadius;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// UIImage+Utils.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Christian Hresko on 5/30/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIImage+Utils.h"
|
||||
|
||||
@implementation UIImage (Utils)
|
||||
|
||||
- (UIImage *)imageWithRoundedCornersSize:(float)cornerRadius {
|
||||
__block UIImageView *imageView;
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
imageView = [[UIImageView alloc] initWithImage:self];
|
||||
// Begin a new image that will be the new image with the rounded corners
|
||||
// (here with the size of an UIImageView)
|
||||
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
|
||||
|
||||
// Add a clip before drawing anything, in the shape of an rounded rect
|
||||
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
|
||||
cornerRadius:cornerRadius] addClip];
|
||||
// Draw your image
|
||||
[self drawInRect:imageView.bounds];
|
||||
|
||||
// Get the image, here setting the UIImageView image
|
||||
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
// Lets forget about that we were drawing
|
||||
UIGraphicsEndImageContext();
|
||||
});
|
||||
|
||||
return imageView.image;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// UIPopOverController+Helpers.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/4/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIPopoverController (Helpers)
|
||||
|
||||
- (void) dismissPopoverAnimated:(BOOL)animated completionHandler:(void(^)(void))completionHandler;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// UIPopOverController+Helpers.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/4/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIPopOverController+Helpers.h"
|
||||
|
||||
@implementation UIPopoverController (Helpers)
|
||||
|
||||
- (void) dismissPopoverAnimated:(BOOL)animated completionHandler:(void(^)(void))completionHandler {
|
||||
[CATransaction begin];
|
||||
[CATransaction setCompletionBlock:completionHandler];
|
||||
[self dismissPopoverAnimated:animated];
|
||||
[CATransaction commit];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// UIScrollView+Auto.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 9/17/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, UIScrollViewDirection) {
|
||||
UIScrollViewDirectionNone,
|
||||
UIScrollViewDirectionHorizontal = 0x1 << 1,
|
||||
UIScrollViewDirectionVertical = 0x1 << 2,
|
||||
UIScrollViewDirectionBoth = UIScrollViewDirectionHorizontal | UIScrollViewDirectionVertical
|
||||
};
|
||||
|
||||
@interface UIScrollView (Auto)
|
||||
|
||||
- (void) setContentSizeForDirection:(UIScrollViewDirection)direction;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// UIScrollView+Auto.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 9/17/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIScrollView+Auto.h"
|
||||
|
||||
@implementation UIScrollView (Auto)
|
||||
|
||||
- (void) setContentSizeForDirection:(UIScrollViewDirection)direction
|
||||
{
|
||||
CGRect contentRect = CGRectZero;
|
||||
for(UIView* view in self.subviews)
|
||||
{
|
||||
if(view.hidden == NO)
|
||||
{
|
||||
contentRect = CGRectUnion(contentRect, view.frame);
|
||||
}
|
||||
}
|
||||
|
||||
if((direction & UIScrollViewDirectionHorizontal) == 0)
|
||||
contentRect.size.width = self.frame.size.width;
|
||||
|
||||
if((direction & UIScrollViewDirectionVertical) == 0)
|
||||
contentRect.size.height = self.frame.size.height;
|
||||
|
||||
self.contentSize = contentRect.size;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// UITabBarItem+CustomBadge.h
|
||||
// CityGlance
|
||||
//
|
||||
// Created by Enrico Vecchio on 05/18/14.
|
||||
// Downloaded from Github and additional functionality added by Kyler Mulherin 10/23/2014.
|
||||
// Copyright (c) 2014 Cityglance SRL. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UITabBarItem (CustomBadge)
|
||||
|
||||
|
||||
|
||||
-(void) setMyAppCustomBadgeValue: (NSString *) value;
|
||||
|
||||
-(void) setCustomBadgeValue: (NSString *) value withColor: (UIColor *) labelColor;
|
||||
|
||||
-(void) setCustomBadgeValue: (NSString *) value withFont: (UIFont *) font andFontColor: (UIColor *) color andBackgroundColor: (UIColor *) backColor;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// UITabBarItem+CustomBadge.m
|
||||
// CityGlance
|
||||
//
|
||||
// Created by Enrico Vecchio on 18/05/14.
|
||||
// Copyright (c) 2014 Cityglance SRL. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UITabBarItem+CustomBadge.h"
|
||||
|
||||
|
||||
#define CUSTOM_BADGE_TAG 99
|
||||
#define OFFSET 0.6f
|
||||
|
||||
|
||||
@implementation UITabBarItem (CustomBadge)
|
||||
|
||||
|
||||
-(void) setMyAppCustomBadgeValue: (NSString *) value
|
||||
{
|
||||
|
||||
UIFont *myAppFont = [UIFont systemFontOfSize:13.0];
|
||||
UIColor *myAppFontColor = [UIColor whiteColor];
|
||||
UIColor *myAppBackColor = [UIColor lightGrayColor];
|
||||
|
||||
[self setCustomBadgeValue:value withFont:myAppFont andFontColor:myAppFontColor andBackgroundColor:myAppBackColor];
|
||||
}
|
||||
|
||||
-(void) setCustomBadgeValue: (NSString *) value
|
||||
withColor: (UIColor *) labelColor
|
||||
{
|
||||
UIFont *myAppFont = [UIFont systemFontOfSize:13.0];
|
||||
UIColor *myAppFontColor = [UIColor whiteColor];
|
||||
|
||||
[self setCustomBadgeValue:value withFont:myAppFont andFontColor:myAppFontColor andBackgroundColor:labelColor];
|
||||
}
|
||||
|
||||
|
||||
-(void) setCustomBadgeValue: (NSString *) value withFont: (UIFont *) font andFontColor: (UIColor *) color andBackgroundColor: (UIColor *) backColor
|
||||
{
|
||||
UIView *v = [self valueForKey:@"view"];
|
||||
|
||||
[self setBadgeValue:value];
|
||||
|
||||
// REMOVE PREVIOUS IF EXIST
|
||||
for(UIView *sv in v.subviews)
|
||||
{
|
||||
if(sv.tag == CUSTOM_BADGE_TAG)
|
||||
{
|
||||
[sv removeFromSuperview];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(UIView *sv in v.subviews)
|
||||
{
|
||||
|
||||
NSString *str = NSStringFromClass([sv class]);
|
||||
|
||||
if([str isEqualToString:@"_UIBadgeView"])
|
||||
{
|
||||
UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, sv.frame.size.width, sv.frame.size.height)];
|
||||
|
||||
|
||||
[l setFont:font];
|
||||
[l setText:value];
|
||||
[l setBackgroundColor:backColor];
|
||||
[l setTextColor:color];
|
||||
[l setTextAlignment:NSTextAlignmentCenter];
|
||||
|
||||
l.layer.cornerRadius = l.frame.size.height/2;
|
||||
l.layer.masksToBounds = YES;
|
||||
|
||||
// Fix for border
|
||||
sv.layer.borderWidth = 1;
|
||||
sv.layer.borderColor = [backColor CGColor];
|
||||
sv.layer.cornerRadius = sv.frame.size.height/2;
|
||||
sv.layer.masksToBounds = YES;
|
||||
|
||||
|
||||
[sv addSubview:l];
|
||||
|
||||
l.tag = CUSTOM_BADGE_TAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// UIView+Position.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 9/17/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIView (Position)
|
||||
|
||||
@property (nonatomic, assign) CGPoint position;
|
||||
@property (nonatomic, assign) CGSize size;
|
||||
|
||||
@property (nonatomic, assign) CGFloat height;
|
||||
@property (nonatomic, assign) CGFloat width;
|
||||
@property (nonatomic, assign) CGFloat x;
|
||||
@property (nonatomic, assign) CGFloat y;
|
||||
|
||||
@property (nonatomic, assign) CGFloat right;
|
||||
@property (nonatomic, assign) CGFloat bottom;
|
||||
|
||||
- (void) centerInFrame:(CGRect)aFrame;
|
||||
@end
|
||||
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// UIView+Position.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 9/17/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIView+Position.h"
|
||||
|
||||
@implementation UIView (Position)
|
||||
|
||||
- (CGPoint) position
|
||||
{
|
||||
return self.frame.origin;
|
||||
}
|
||||
|
||||
- (CGFloat) height
|
||||
{
|
||||
return self.frame.size.height;
|
||||
}
|
||||
|
||||
- (CGFloat) width
|
||||
{
|
||||
return self.frame.size.width;
|
||||
}
|
||||
|
||||
- (CGFloat) x
|
||||
{
|
||||
return self.frame.origin.x;
|
||||
}
|
||||
|
||||
- (CGFloat) y
|
||||
{
|
||||
return self.frame.origin.y;
|
||||
}
|
||||
|
||||
- (CGFloat) centerY
|
||||
{
|
||||
return self.center.y;
|
||||
}
|
||||
|
||||
- (CGFloat) centerX
|
||||
{
|
||||
return self.center.x;
|
||||
}
|
||||
|
||||
- (CGSize) size
|
||||
{
|
||||
return self.frame.size;
|
||||
}
|
||||
|
||||
- (void)setPosition:(CGPoint)newPosition
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.origin = newPosition;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (void) setHeight:(CGFloat)newHeight
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.size.height = newHeight;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (void) setWidth:(CGFloat)newWidth
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.size.width = newWidth;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (void) setX:(CGFloat)newX
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.x = newX;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (void) setY:(CGFloat)newY
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.y = newY;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (void) setSize:(CGSize)size
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.size = size;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat) right
|
||||
{
|
||||
return self.x + self.width;
|
||||
}
|
||||
|
||||
- (void)setRight:(CGFloat)right
|
||||
{
|
||||
self.x = right - self.width;
|
||||
}
|
||||
|
||||
- (CGFloat) bottom
|
||||
{
|
||||
return self.y + self.height;
|
||||
}
|
||||
|
||||
- (void)setBottom:(CGFloat)bottom
|
||||
{
|
||||
self.y = bottom - self.height;
|
||||
}
|
||||
|
||||
- (void) centerInFrame:(CGRect)aFrame
|
||||
{
|
||||
float h = [self height];
|
||||
float w = [self width];
|
||||
|
||||
//center our frame to the provided frame
|
||||
CGRect centeredFrame = CGRectMake(CGRectGetMidX(aFrame) - (w * 0.5),
|
||||
CGRectGetMidY(aFrame) - (h * 0.5),
|
||||
w, h);
|
||||
self.frame = centeredFrame;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// UIView+DTDebug.h
|
||||
// DTFoundation
|
||||
//
|
||||
// Created by Stefan Gugarel on 2/8/13.
|
||||
// Copyright (c) 2013 Cocoanetics. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIView.h>
|
||||
|
||||
/**
|
||||
Methods useful for debugging problems with UIView instances.
|
||||
*/
|
||||
|
||||
@interface UIView (DTDebug)
|
||||
|
||||
/**
|
||||
@name Main Thread Checking
|
||||
*/
|
||||
|
||||
/**
|
||||
Toggles on/off main thread checking on several methods of UIView.
|
||||
|
||||
Currently the following methods are swizzeled and checked:
|
||||
|
||||
- setNeedsDisplay
|
||||
- setNeedsDisplayInRect:
|
||||
- setNeedsLayout
|
||||
|
||||
Those are triggered by a variety of methods in UIView, e.g. setBackgroundColor and thus it is not necessary to swizzle all of them.
|
||||
*/
|
||||
+ (void)toggleViewMainThreadChecking;
|
||||
|
||||
/**
|
||||
Method that gets called if one of the important methods of UIView is not being called on a main queue.
|
||||
|
||||
Toggle this on/off with <toggleViewMainThreadChecking>. Break on -[UIView methodCalledNotFromMainThread:] to catch it in debugger.
|
||||
@param methodName Symbolic name of the method being called
|
||||
*/
|
||||
- (void)methodCalledNotFromMainThread:(NSString *)methodName;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
//
|
||||
// UIView+DTDebug.m
|
||||
// DTFoundation
|
||||
//
|
||||
// Created by Stefan Gugarel on 2/8/13.
|
||||
// Copyright (c) 2013 Cocoanetics. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIView+RBDebug.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation UIView (DTDebug)
|
||||
|
||||
+ (void)swizzleMethod:(SEL)selector withMethod:(SEL)otherSelector
|
||||
{
|
||||
// my own class is being targetted
|
||||
Class c = [self class];
|
||||
|
||||
// get the methods from the selectors
|
||||
Method originalMethod = class_getInstanceMethod(c, selector);
|
||||
Method otherMethod = class_getInstanceMethod(c, otherSelector);
|
||||
|
||||
if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod)))
|
||||
{
|
||||
class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
|
||||
}
|
||||
else
|
||||
{
|
||||
method_exchangeImplementations(originalMethod, otherMethod);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)methodCalledNotFromMainThread:(NSString *)methodName
|
||||
{
|
||||
NSLog(@"-[%@ %@] being called on background queue. Break on -[UIView methodCalledNotFromMainThread:] to find out where", NSStringFromClass([self class]), methodName);
|
||||
}
|
||||
|
||||
- (void)_setNeedsLayout_MainThreadCheck
|
||||
{
|
||||
if (![NSThread isMainThread])
|
||||
{
|
||||
[self methodCalledNotFromMainThread:NSStringFromSelector(_cmd)];
|
||||
}
|
||||
|
||||
// not really an endless loop, this calls the original
|
||||
[self _setNeedsLayout_MainThreadCheck];
|
||||
}
|
||||
|
||||
- (void)_setNeedsDisplay_MainThreadCheck
|
||||
{
|
||||
if (![NSThread isMainThread])
|
||||
{
|
||||
[self methodCalledNotFromMainThread:NSStringFromSelector(_cmd)];
|
||||
}
|
||||
|
||||
// not really an endless loop, this calls the original
|
||||
[self _setNeedsDisplay_MainThreadCheck];
|
||||
}
|
||||
|
||||
- (void)_setNeedsDisplayInRect_MainThreadCheck:(CGRect)rect
|
||||
{
|
||||
if (![NSThread isMainThread])
|
||||
{
|
||||
[self methodCalledNotFromMainThread:NSStringFromSelector(_cmd)];
|
||||
}
|
||||
|
||||
// not really an endless loop, this calls the original
|
||||
[self _setNeedsDisplayInRect_MainThreadCheck:rect];
|
||||
}
|
||||
|
||||
+ (void)toggleViewMainThreadChecking
|
||||
{
|
||||
[UIView swizzleMethod:@selector(setNeedsLayout) withMethod:@selector(_setNeedsLayout_MainThreadCheck)];
|
||||
[UIView swizzleMethod:@selector(setNeedsDisplay) withMethod:@selector(_setNeedsDisplay_MainThreadCheck)];
|
||||
[UIView swizzleMethod:@selector(setNeedsDisplayInRect:) withMethod:@selector(_setNeedsDisplayInRect_MainThreadCheck:)];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// UIView+Helpers.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 6/11/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIViewController (Helpers)
|
||||
|
||||
// Returns the most topmost view controller
|
||||
+ (UIViewController*) topViewController;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// UIView+Helpers.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ariel Lichtin on 6/11/14.
|
||||
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIViewController+Helpers.h"
|
||||
#import "RobloxTheme.h"
|
||||
|
||||
@implementation UIViewController (Helpers)
|
||||
|
||||
+ (UIViewController*) topViewController
|
||||
{
|
||||
return [UIViewController topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
|
||||
}
|
||||
|
||||
+ (UIViewController *)topViewController:(UIViewController *)rootViewController
|
||||
{
|
||||
if (rootViewController.presentedViewController == nil)
|
||||
{
|
||||
return rootViewController;
|
||||
}
|
||||
else if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]])
|
||||
{
|
||||
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
|
||||
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
|
||||
return [self topViewController:lastViewController];
|
||||
}
|
||||
else if([rootViewController.presentedViewController isKindOfClass:[UIAlertController class]])
|
||||
{
|
||||
return rootViewController;
|
||||
}
|
||||
else
|
||||
{
|
||||
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
|
||||
return [self topViewController:presentedViewController];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// UIWebView+RBXUIWebView.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/30/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RBXWebViewProtocol.h"
|
||||
|
||||
@interface UIWebView (RBXUIWebView) <RBXWebViewProtocol>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// UIWebView+RBXUIWebView.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/30/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIWebView+RBXUIWebView.h"
|
||||
#import "RBXFunctions.h"
|
||||
#import "RBHybridBridge.h"
|
||||
|
||||
@implementation UIWebView (RBXUIWebView)
|
||||
|
||||
@dynamic URL;
|
||||
|
||||
- (void) setDelegateController:(id)delegate
|
||||
{
|
||||
[self setDelegate:delegate];
|
||||
}
|
||||
|
||||
- (NSURL *) URL
|
||||
{
|
||||
return [[self request] URL];
|
||||
}
|
||||
|
||||
- (void) evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler
|
||||
{
|
||||
NSString *js = [self stringByEvaluatingJavaScriptFromString:javaScriptString];
|
||||
|
||||
if (completionHandler) {
|
||||
completionHandler(js, nil);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) canGoBackInHistory
|
||||
{
|
||||
BOOL val = self.canGoBack;
|
||||
return val;
|
||||
}
|
||||
|
||||
- (BOOL) canGoForwardInHistory
|
||||
{
|
||||
BOOL val = self.canGoForward;
|
||||
return val;
|
||||
}
|
||||
|
||||
- (void) goBackInHistory
|
||||
{
|
||||
if ([self canGoBack]) {
|
||||
[self goBack];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) goForwardInHistory
|
||||
{
|
||||
if ([self canGoForward]) {
|
||||
[self goForward];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) enableScrolling:(BOOL)enable
|
||||
{
|
||||
self.scrollView.scrollEnabled = enable;
|
||||
}
|
||||
|
||||
- (void) enableMultipleTouch:(BOOL)enable
|
||||
{
|
||||
self.multipleTouchEnabled = enable;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// WKWebView+RBXWKWebView.h
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/30/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
#import "RBXWebViewProtocol.h"
|
||||
|
||||
@interface WKWebView (RBXWKWebView) <RBXWebViewProtocol>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// WKWebView+RBXWKWebView.m
|
||||
// RobloxMobile
|
||||
//
|
||||
// Created by Ashish Jain on 9/30/15.
|
||||
// Copyright (c) 2015 ROBLOX. All rights reserved.
|
||||
//
|
||||
|
||||
#import "WKWebView+RBXWKWebView.h"
|
||||
|
||||
#import "LoginManager.h"
|
||||
#import "RBXFunctions.h"
|
||||
#import "RBHybridBridge.h"
|
||||
#import "RobloxInfo.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation WKWebView (RBXWKWebView)
|
||||
|
||||
- (void) setDelegateController:(id)delegate
|
||||
{
|
||||
[self setNavigationDelegate:delegate];
|
||||
[self setUIDelegate:delegate];
|
||||
}
|
||||
|
||||
- (NSURLRequest *) request
|
||||
{
|
||||
return objc_getAssociatedObject(self, @selector(request));
|
||||
}
|
||||
|
||||
- (void) setRequest:(NSURLRequest *)request
|
||||
{
|
||||
objc_setAssociatedObject(self, @selector(request), request, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
+ (void) load
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
|
||||
// We want to make sure this is only done once!
|
||||
dispatch_once(&onceToken, ^{
|
||||
Class class = [self class];
|
||||
|
||||
// Get the representation of the method names to swizzle.
|
||||
SEL originalSelector = @selector(loadRequest:);
|
||||
SEL swizzledSelector = @selector(altLoadRequest:);
|
||||
|
||||
// Get references to the methods to swizzle.
|
||||
Method originalMethod = class_getInstanceMethod(class, originalSelector);
|
||||
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
|
||||
|
||||
// Attempt to add the new method in place of the old method.
|
||||
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
|
||||
|
||||
// If we succeeded, put the old method in place of the new method.
|
||||
if (didAddMethod) {
|
||||
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
|
||||
} else {
|
||||
// Otherwise, just swap their implementations.
|
||||
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 2015.1026 ajain - This requires a little mental juggling. We do a swizzle (replace implementations) of
|
||||
// the loadRequest method with altLoadRequest. That way, every time another class calls loadRequest on a WKWebView object, it'll
|
||||
// actually execute the altLoadRequest method.
|
||||
|
||||
// Example: Outside class calls [[WKWebView instance] loadRequest] --> executes
|
||||
// altLoadRequest implementation (custom code below) --> calls
|
||||
// [self altLoadRequest:mutableRequest] --> executes
|
||||
// original loadRequest implementation (apple wkwebview code).
|
||||
|
||||
// The method swizzling is why calling altLoadRequest is NOT a recursive method call.
|
||||
|
||||
- (void) altLoadRequest:(NSURLRequest *)request
|
||||
{
|
||||
NSArray *cookies = [LoginManager cookies];
|
||||
|
||||
NSDictionary *cookiesDict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
|
||||
|
||||
NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithDictionary:request.allHTTPHeaderFields];
|
||||
[requestHeaders addEntriesFromDictionary:cookiesDict];
|
||||
|
||||
NSMutableURLRequest *mutableRequest = request.mutableCopy;
|
||||
[mutableRequest setAllHTTPHeaderFields:requestHeaders];
|
||||
|
||||
[self setRequest:mutableRequest];
|
||||
|
||||
// 2015.1026 ajain - Since we swizzled with loadRequest, this will actually call the original loadRequest.
|
||||
[self altLoadRequest:mutableRequest];
|
||||
}
|
||||
|
||||
- (BOOL) canGoBackInHistory
|
||||
{
|
||||
BOOL val = self.canGoBack;
|
||||
return val;
|
||||
}
|
||||
|
||||
- (BOOL) canGoForwardInHistory
|
||||
{
|
||||
BOOL val = self.canGoForward;
|
||||
return val;
|
||||
}
|
||||
|
||||
- (void) goBackInHistory
|
||||
{
|
||||
if ([self canGoBack]) {
|
||||
[self goBack];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) goForwardInHistory
|
||||
{
|
||||
if ([self canGoForward]) {
|
||||
[self goForward];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) enableScrolling:(BOOL)enable
|
||||
{
|
||||
self.scrollView.scrollEnabled = enable;
|
||||
}
|
||||
|
||||
- (void) enableMultipleTouch:(BOOL)enable
|
||||
{
|
||||
self.multipleTouchEnabled = enable;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user