open source
@@ -0,0 +1,14 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "LaunchView.h"
|
||||
|
||||
@class NavViewController;
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
{
|
||||
@public
|
||||
UIBackgroundTaskIdentifier m_kBackgroundTask;
|
||||
}
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
@property (strong, nonatomic) LaunchView *launchView;
|
||||
@property (strong, nonatomic) NavViewController* navigationController;
|
||||
@end
|
||||
@@ -0,0 +1,60 @@
|
||||
#import "AppDelegate.h"
|
||||
#import "ViewController.h"
|
||||
#import "conchRuntime.h"
|
||||
#import "NavViewController.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] ;
|
||||
ViewController* pViewController = [[ViewController alloc] init];
|
||||
//_window.rootViewController = pViewController;
|
||||
[_window makeKeyAndVisible];
|
||||
|
||||
_launchView = [[LaunchView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
[_window.rootViewController.view addSubview:_launchView.view];
|
||||
|
||||
self.navigationController = [[NavViewController alloc] init];
|
||||
[self.navigationController pushViewController:pViewController animated:YES];
|
||||
_window.rootViewController = self.navigationController;
|
||||
[_window.rootViewController.view addSubview:_launchView.view];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
m_kBackgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
|
||||
if(m_kBackgroundTask != UIBackgroundTaskInvalid )
|
||||
{
|
||||
NSLog(@">>>>>backgroundTask end");
|
||||
[application endBackgroundTask:m_kBackgroundTask];
|
||||
m_kBackgroundTask = UIBackgroundTaskInvalid;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
@end
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "58.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "87.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "80.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "120.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "120-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "180.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "29.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "58-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "40.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "80-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "76.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "152.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "layabox.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "layabox-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "layabox-2.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "close-2.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "close.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "close-1.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "line.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "line-2.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "line-1.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "pick_bg.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "pick_bg-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "pick_bg-2.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="LaunchScreen" id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Launch" highlighted="YES" translatesAutoresizingMaskIntoConstraints="NO" id="map-GD-PNR">
|
||||
<rect key="frame" x="93" y="294" width="188" height="78"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E2Q-uj-XYa">
|
||||
<rect key="frame" x="187" y="567" width="0.0" height="0.0"/>
|
||||
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="E2Q-uj-XYa" secondAttribute="bottom" constant="100" id="8T1-jD-1Th"/>
|
||||
<constraint firstItem="map-GD-PNR" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="DEr-N7-3nu"/>
|
||||
<constraint firstItem="map-GD-PNR" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="U73-tZ-TAg"/>
|
||||
<constraint firstItem="E2Q-uj-XYa" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="VGz-jI-kNC"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="52" y="374.66266866566718"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Launch" width="188" height="78"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>LayaBox2.0</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string></string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,6 @@
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@interface JSBridge: NSObject
|
||||
+(void)onScanResult:(NSString*)result;
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#import "JSBridge.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "ViewController.h"
|
||||
#import "UIFloatPanel.h"
|
||||
#import "ScanViewController.h"
|
||||
#import <UIKit/UINavigationController.h>
|
||||
#import "NavViewController.h"
|
||||
|
||||
@implementation JSBridge
|
||||
|
||||
+(void)hideSplash
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate.launchView hide];
|
||||
});
|
||||
}
|
||||
+(void)setTips:(NSArray*)tips
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
appDelegate.launchView.tips = tips;
|
||||
});
|
||||
}
|
||||
+(void)setFontColor:(NSString*)color
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate.launchView setFontColor:color];
|
||||
});
|
||||
}
|
||||
+(void)bgColor:(NSString*)color
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate.launchView setBackgroundColor:color];
|
||||
});
|
||||
}
|
||||
+(void)loading:(NSNumber*)percent
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate.launchView setPercent:percent.integerValue];
|
||||
});
|
||||
}
|
||||
+(void)showTextInfo:(NSNumber*)show
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate.launchView showTextInfo:show.intValue > 0];
|
||||
});
|
||||
}
|
||||
+(void)showScanner:(NSNumber*)show
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
if (show.intValue > 0)
|
||||
{
|
||||
[appDelegate.navigationController presentViewController:[[ScanViewController alloc] init] animated:NO completion:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
+(void)onScanResult:(NSString*)result
|
||||
{
|
||||
NSString* js = [[NSString alloc] initWithFormat:@"script.UIController.instance.onScanResult('%@')", result];
|
||||
[[conchRuntime GetIOSConchRuntime] runJS:js];
|
||||
}
|
||||
+(void)showFloatPanel:(NSNumber*)show
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (show.intValue > 0)
|
||||
{
|
||||
[ViewController GetIOSViewController]->m_floatPanel.hidden = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
[ViewController GetIOSViewController]->m_floatPanel.hidden = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface LaunchView : NSObject
|
||||
-(id)initWithFrame:(CGRect)frame;
|
||||
-(void)hide;
|
||||
-(void)setFontColor:(NSString*)color;
|
||||
-(void)setBackgroundColor:(NSString*)color;
|
||||
-(void)showTextInfo:(Boolean)show;
|
||||
@property (strong, nonatomic) UIView* view;
|
||||
@property (strong, nonatomic) NSArray* tips;
|
||||
@property (assign, nonatomic) NSInteger percent;
|
||||
@end
|
||||
@@ -0,0 +1,146 @@
|
||||
#import "LaunchView.h"
|
||||
|
||||
static const NSTimeInterval REFRESH_INTERVAL = 1.0;
|
||||
static const int LEAST_SHOW_TIME = 2;
|
||||
@interface LaunchView()
|
||||
@property (strong, nonatomic) UIViewController* viewController;
|
||||
@property (assign, nonatomic) NSTimeInterval startTime;
|
||||
@property (strong, nonatomic) dispatch_source_t timer;
|
||||
@property (assign, nonatomic) NSInteger index;
|
||||
@end
|
||||
@implementation LaunchView
|
||||
-(id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super init];
|
||||
if( self != nil )
|
||||
{
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil];
|
||||
_viewController = [storyboard instantiateViewControllerWithIdentifier:@"LaunchScreen"];
|
||||
_view = _viewController.view;
|
||||
_view.frame = frame;
|
||||
_startTime = [[NSDate date] timeIntervalSince1970];
|
||||
_percent = 0;
|
||||
_index = 0;
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_queue_t queue = dispatch_get_main_queue();
|
||||
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
|
||||
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), REFRESH_INTERVAL * NSEC_PER_SEC, 0);
|
||||
dispatch_source_set_event_handler(_timer, ^{
|
||||
NSInteger length = weakSelf.tips != nil ? weakSelf.tips.count : 0;
|
||||
if (length > 0) {
|
||||
if (weakSelf.index >= length) {
|
||||
weakSelf.index = 0;
|
||||
}
|
||||
for (UIView* subView in weakSelf.view.subviews) {
|
||||
if ([subView isKindOfClass:[UILabel class]]) {
|
||||
UILabel* label = (UILabel*)subView;
|
||||
label.text = [NSString stringWithFormat:@"%@(%%%ld)", [weakSelf.tips objectAtIndex:weakSelf.index], (long)weakSelf.percent];
|
||||
}
|
||||
}
|
||||
weakSelf.index++;
|
||||
}
|
||||
});
|
||||
dispatch_resume(_timer);
|
||||
|
||||
return self;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
-(void)hide
|
||||
{
|
||||
NSTimeInterval showTime = [[NSDate date] timeIntervalSince1970] - _startTime;
|
||||
if (showTime >= LEAST_SHOW_TIME)
|
||||
{
|
||||
[_viewController.view removeFromSuperview];
|
||||
dispatch_source_cancel(_timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSTimeInterval timeLeft = LEAST_SHOW_TIME - showTime;
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeLeft * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[weakSelf.viewController.view removeFromSuperview];
|
||||
dispatch_source_cancel(weakSelf.timer);
|
||||
});
|
||||
}
|
||||
}
|
||||
+ (UIColor *)colorWithHexString:(NSString*)color
|
||||
{
|
||||
NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
|
||||
if ([cString length] < 6) {
|
||||
return [UIColor clearColor];
|
||||
}
|
||||
if ([cString hasPrefix:@"0X"])
|
||||
cString = [cString substringFromIndex:2];
|
||||
if ([cString hasPrefix:@"#"])
|
||||
cString = [cString substringFromIndex:1];
|
||||
if ([cString length] != 6)
|
||||
return [UIColor clearColor];
|
||||
|
||||
NSRange range;
|
||||
range.location = 0;
|
||||
range.length = 2;
|
||||
|
||||
NSString *rString = [cString substringWithRange:range];
|
||||
|
||||
range.location = 2;
|
||||
NSString *gString = [cString substringWithRange:range];
|
||||
|
||||
range.location = 4;
|
||||
NSString *bString = [cString substringWithRange:range];
|
||||
|
||||
unsigned int r, g, b;
|
||||
[[NSScanner scannerWithString:rString] scanHexInt:&r];
|
||||
[[NSScanner scannerWithString:gString] scanHexInt:&g];
|
||||
[[NSScanner scannerWithString:bString] scanHexInt:&b];
|
||||
|
||||
return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f];
|
||||
}
|
||||
-(void)setFontColor:(NSString*)color
|
||||
{
|
||||
for (UIView* subView in self.view.subviews) {
|
||||
if ([subView isKindOfClass:[UILabel class]]) {
|
||||
UILabel* label = (UILabel*)subView;
|
||||
label.textColor = [LaunchView colorWithHexString:color];
|
||||
}
|
||||
}
|
||||
}
|
||||
-(void)setPercent:(NSInteger)percent
|
||||
{
|
||||
_percent = percent;
|
||||
if (_percent > 100) {
|
||||
_percent = 100;
|
||||
}
|
||||
if (_percent < 0) {
|
||||
_percent = 0;
|
||||
}
|
||||
NSInteger length = self.tips != nil ? self.tips.count : 0;
|
||||
if (length > 0) {
|
||||
if (self.index >= length) {
|
||||
self.index = 0;
|
||||
}
|
||||
for (UIView* subView in self.view.subviews) {
|
||||
if ([subView isKindOfClass:[UILabel class]]) {
|
||||
UILabel* label = (UILabel*)subView;
|
||||
label.text = [NSString stringWithFormat:@"%@(%ld%%)", [self.tips objectAtIndex:self.index], (long)self.percent];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_percent == 100) {
|
||||
[self hide];
|
||||
}
|
||||
}
|
||||
-(void)setBackgroundColor:(NSString*)color
|
||||
{
|
||||
_view.backgroundColor = [LaunchView colorWithHexString:color];
|
||||
}
|
||||
-(void)showTextInfo:(Boolean)show
|
||||
{
|
||||
for (UIView* subView in self.view.subviews) {
|
||||
if ([subView isKindOfClass:[UILabel class]]) {
|
||||
UILabel* label = (UILabel*)subView;
|
||||
label.hidden = !show;
|
||||
}
|
||||
}
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,11 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
#import <conchRuntime.h>
|
||||
|
||||
@interface NavViewController : UINavigationController
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#import "NavViewController.h"
|
||||
|
||||
@implementation NavViewController
|
||||
|
||||
- (void)viewDidLoad{
|
||||
[super viewDidLoad];
|
||||
self.navigationBar.hidden = TRUE;
|
||||
}
|
||||
- (BOOL)shouldAutorotate{
|
||||
return [[self.viewControllers lastObject]shouldAutorotate];
|
||||
}
|
||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
|
||||
return [[self.viewControllers lastObject]supportedInterfaceOrientations];
|
||||
//return [conchConfig GetInstance]->m_nOrientationType;
|
||||
}
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
|
||||
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ScanViewController : UIViewController
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
|
||||
#import "ScanViewController.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import "ViewController.h"
|
||||
#import "JSBridge.h"
|
||||
|
||||
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
|
||||
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
|
||||
#define SCREEN_BOUNDS [UIScreen mainScreen].bounds
|
||||
|
||||
#define TOP (SCREEN_HEIGHT-220)/2
|
||||
#define LEFT (SCREEN_WIDTH-220)/2
|
||||
|
||||
#define kScanRect CGRectMake(LEFT, TOP, 220, 220)
|
||||
|
||||
@interface ScanViewController ()<AVCaptureMetadataOutputObjectsDelegate>{
|
||||
int num;
|
||||
BOOL upOrdown;
|
||||
NSTimer * timer;
|
||||
CAShapeLayer *cropLayer;
|
||||
}
|
||||
@property (strong,nonatomic)AVCaptureDevice * device;
|
||||
@property (strong,nonatomic)AVCaptureDeviceInput * input;
|
||||
@property (strong,nonatomic)AVCaptureMetadataOutput * output;
|
||||
@property (strong,nonatomic)AVCaptureSession * session;
|
||||
@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;
|
||||
@property (strong,nonatomic)UIImageView * line;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ScanViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(void)configView{
|
||||
|
||||
UIImageView * imageView = [[UIImageView alloc]initWithFrame:kScanRect];
|
||||
imageView.image = [UIImage imageNamed:@"pick_bg"];
|
||||
[self.view addSubview:imageView];
|
||||
|
||||
upOrdown = NO;
|
||||
num =0;
|
||||
_line = [[UIImageView alloc] initWithFrame:CGRectMake(LEFT, TOP+10, 220, 2)];
|
||||
_line.image = [UIImage imageNamed:@"line.png"];
|
||||
[self.view addSubview:_line];
|
||||
|
||||
timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
|
||||
|
||||
|
||||
UIImage* pImageButtonBack = [UIImage imageNamed:@"close.png"];
|
||||
|
||||
float offset = 30;
|
||||
float width = pImageButtonBack.size.width;
|
||||
float height = pImageButtonBack.size.height;
|
||||
|
||||
UIButton* pButtonBack = [[UIButton alloc] initWithFrame:CGRectMake(0,0,width,height)];
|
||||
pButtonBack.titleEdgeInsets = UIEdgeInsetsMake(44.0f, 0.0f, 0.0f, 0.0f);
|
||||
//[pButtonBack setTitle:@"后退" forState:UIControlStateNormal];
|
||||
[pButtonBack setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
|
||||
pButtonBack.titleLabel.font = [UIFont systemFontOfSize:13.0];
|
||||
[pButtonBack setBackgroundImage:pImageButtonBack forState:UIControlStateNormal];
|
||||
pButtonBack.center = CGPointMake(offset,offset);
|
||||
[pButtonBack addTarget:self action:@selector(buttonClickBack:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.view addSubview:pButtonBack];
|
||||
|
||||
}
|
||||
-(void)buttonClickBack:(id)sender
|
||||
{
|
||||
[self dismissViewControllerAnimated:NO completion:nil];
|
||||
}
|
||||
|
||||
-(void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear: animated];
|
||||
[self configView];
|
||||
//[self setCropRect:kScanRect];
|
||||
[self performSelector:@selector(setupCamera) withObject:nil afterDelay:0.3];
|
||||
}
|
||||
|
||||
-(void)animation1
|
||||
{
|
||||
if (upOrdown == NO) {
|
||||
num ++;
|
||||
_line.frame = CGRectMake(LEFT, TOP+10+2*num, 220, 2);
|
||||
if (2*num == 200) {
|
||||
upOrdown = YES;
|
||||
}
|
||||
}
|
||||
else {
|
||||
num --;
|
||||
_line.frame = CGRectMake(LEFT, TOP+10+2*num, 220, 2);
|
||||
if (num == 0) {
|
||||
upOrdown = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setCropRect:(CGRect)cropRect{
|
||||
cropLayer = [[CAShapeLayer alloc] init];
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathAddRect(path, nil, cropRect);
|
||||
CGPathAddRect(path, nil, self.view.bounds);
|
||||
|
||||
[cropLayer setFillRule:kCAFillRuleEvenOdd];
|
||||
[cropLayer setPath:path];
|
||||
[cropLayer setFillColor:[UIColor blackColor].CGColor];
|
||||
[cropLayer setOpacity:0.6];
|
||||
|
||||
|
||||
[cropLayer setNeedsDisplay];
|
||||
|
||||
[self.view.layer addSublayer:cropLayer];
|
||||
}
|
||||
- (void)setupCamera
|
||||
{
|
||||
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
||||
if (device==nil) {
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"设备没有摄像头" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
return;
|
||||
}
|
||||
// Device
|
||||
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
||||
|
||||
// Input
|
||||
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
|
||||
|
||||
// Output
|
||||
_output = [[AVCaptureMetadataOutput alloc]init];
|
||||
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
|
||||
|
||||
//设置扫描区域
|
||||
CGFloat top = TOP/SCREEN_HEIGHT;
|
||||
CGFloat left = LEFT/SCREEN_WIDTH;
|
||||
CGFloat width = 220/SCREEN_WIDTH;
|
||||
CGFloat height = 220/SCREEN_HEIGHT;
|
||||
///top 与 left 互换 width 与 height 互换
|
||||
[_output setRectOfInterest:CGRectMake(top,left, height, width)];
|
||||
|
||||
|
||||
// Session
|
||||
_session = [[AVCaptureSession alloc]init];
|
||||
[_session setSessionPreset:AVCaptureSessionPresetHigh];
|
||||
if ([_session canAddInput:self.input])
|
||||
{
|
||||
[_session addInput:self.input];
|
||||
}
|
||||
|
||||
if ([_session canAddOutput:self.output])
|
||||
{
|
||||
[_session addOutput:self.output];
|
||||
}
|
||||
|
||||
// 条码类型 AVMetadataObjectTypeQRCode
|
||||
[_output setMetadataObjectTypes:[NSArray arrayWithObjects:AVMetadataObjectTypeQRCode, nil]];
|
||||
|
||||
// Preview
|
||||
_preview =[AVCaptureVideoPreviewLayer layerWithSession:_session];
|
||||
_preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||||
_preview.frame =self.view.layer.bounds;
|
||||
[self.view.layer insertSublayer:_preview atIndex:0];
|
||||
|
||||
// Start
|
||||
[_session startRunning];
|
||||
}
|
||||
|
||||
#pragma mark AVCaptureMetadataOutputObjectsDelegate
|
||||
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
|
||||
{
|
||||
NSString *stringValue;
|
||||
|
||||
if ([metadataObjects count] >0)
|
||||
{
|
||||
//停止扫描
|
||||
[_session stopRunning];
|
||||
[timer setFireDate:[NSDate distantFuture]];
|
||||
|
||||
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
|
||||
stringValue = metadataObject.stringValue;
|
||||
|
||||
[JSBridge onScanResult:stringValue];
|
||||
NSLog(@"scan result:%@",stringValue);
|
||||
[self dismissViewControllerAnimated:NO completion:nil];
|
||||
} else {
|
||||
NSLog(@"no scan result");
|
||||
[self dismissViewControllerAnimated:NO completion:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
- (BOOL)shouldAutorotate
|
||||
{
|
||||
return YES;//支持转屏
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
- (BOOL)prefersStatusBarHidden
|
||||
{
|
||||
return YES;//隐藏为YES,显示为NO
|
||||
}
|
||||
-(NSUInteger)supportedInterfaceOrientations
|
||||
{
|
||||
return UIInterfaceOrientationMaskPortrait;
|
||||
}
|
||||
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||
return UIInterfaceOrientationPortrait;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
|
||||
@interface UIFloatPanel : UIImageView
|
||||
{
|
||||
GLKView* m_pGLView;
|
||||
UIButton* m_pRefreshBtn;
|
||||
UIButton* m_pBackBtn;
|
||||
}
|
||||
-(id)initWithParentView:(GLKView*)pGLView;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
|
||||
#import "UIFloatPanel.h"
|
||||
#import <objc/runtime.h>
|
||||
#import "conchRuntime.h"
|
||||
#import "conchConfig.h"
|
||||
#import <UIKit/UIAlertController.h>
|
||||
#import "AppDelegate.h"
|
||||
#import "ScanViewController.h"
|
||||
#import "NavViewController.h"
|
||||
|
||||
@implementation UIFloatPanel
|
||||
|
||||
-(id)initWithParentView:(GLKView*)pGLView
|
||||
{
|
||||
m_pGLView = pGLView;
|
||||
UIImage* m_pImagePanel = [self imagesNamedFromCustomBundle:@"panel.png"];
|
||||
self = [super initWithFrame:CGRectMake(0,0,m_pImagePanel.size.width,m_pImagePanel.size.height)];
|
||||
if( self != nil )
|
||||
{
|
||||
self.userInteractionEnabled = TRUE;
|
||||
[self setImage:m_pImagePanel];
|
||||
[m_pGLView addSubview:self];
|
||||
[self resetPosition];
|
||||
|
||||
UIImage* pImage = [self imagesNamedFromCustomBundle:@"btn_refresh_normal.png"];
|
||||
|
||||
float offset = m_pImagePanel.size.width * 0.15f;
|
||||
float distance = (m_pImagePanel.size.width - 2 * offset) * 0.5f;
|
||||
|
||||
m_pRefreshBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, pImage.size.width, pImage.size.height)];
|
||||
[m_pRefreshBtn setImage:[self imagesNamedFromCustomBundle:@"btn_refresh_normal.png"] forState:UIControlStateNormal];
|
||||
[m_pRefreshBtn setImage:[self imagesNamedFromCustomBundle:@"btn_refresh_focused.png"] forState:UIControlStateHighlighted];
|
||||
[m_pRefreshBtn setImage:[self imagesNamedFromCustomBundle:@"btn_refresh_pressed.png"] forState:UIControlStateSelected];
|
||||
m_pRefreshBtn.center = CGPointMake(offset + distance * 0.5f,m_pImagePanel.size.height * 0.5f);
|
||||
[m_pRefreshBtn addTarget:self action:@selector(buttonClickRefresh:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self addSubview:m_pRefreshBtn];
|
||||
|
||||
pImage = [self imagesNamedFromCustomBundle:@"btn_back_normal.png"];
|
||||
m_pBackBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, pImage.size.width, pImage.size.height)];
|
||||
[m_pBackBtn setImage:[self imagesNamedFromCustomBundle:@"btn_back_normal.png"] forState:UIControlStateNormal];
|
||||
[m_pBackBtn setImage:[self imagesNamedFromCustomBundle:@"btn_back_focused.png"] forState:UIControlStateHighlighted];
|
||||
[m_pBackBtn setImage:[self imagesNamedFromCustomBundle:@"btn_back_pressed.png"] forState:UIControlStateSelected];
|
||||
[m_pBackBtn addTarget:self action:@selector(buttonClickBack:) forControlEvents:UIControlEventTouchUpInside];
|
||||
m_pBackBtn.center = CGPointMake(offset + distance * 1.5f, m_pImagePanel.size.height * 0.5f);
|
||||
[self addSubview:m_pBackBtn];
|
||||
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(orientChange:)
|
||||
name:UIDeviceOrientationDidChangeNotification
|
||||
object:nil];
|
||||
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
-(void)buttonClickBack:(id)sender
|
||||
{
|
||||
[[conchRuntime GetIOSConchRuntime] runJS:@"history.back()"];
|
||||
}
|
||||
-(void)buttonClickRefresh:(id)sender
|
||||
{
|
||||
[[conchRuntime GetIOSConchRuntime] runJS:@"reloadJS(true)"];
|
||||
}
|
||||
- (UIImage *)imagesNamedFromCustomBundle:(NSString *)imgName
|
||||
{
|
||||
NSString *bundlePath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:@"libconchRuntime.bundle"];
|
||||
NSString *img_path = [bundlePath stringByAppendingPathComponent:imgName];
|
||||
return [UIImage imageWithContentsOfFile:img_path];
|
||||
}
|
||||
-(void)resetPosition
|
||||
{
|
||||
self.center = CGPointMake([[UIScreen mainScreen] bounds].size.width - 0.5f * self.bounds.size.width - 10, 30);
|
||||
}
|
||||
-(void)orientChange:(NSNotification *)aNotification
|
||||
{
|
||||
[self resetPosition];
|
||||
}
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
#import <conchRuntime.h>
|
||||
|
||||
@class UIFloatPanel;
|
||||
@interface ViewController : GLKViewController
|
||||
{
|
||||
@public
|
||||
|
||||
GLKView* m_pGLKView;
|
||||
|
||||
EAGLContext* m_pGLContext;
|
||||
|
||||
conchRuntime* m_pConchRuntime;
|
||||
CADisplayLink* m_displayLink;
|
||||
UIFloatPanel* m_floatPanel;
|
||||
}
|
||||
+(ViewController*)GetIOSViewController;
|
||||
-(id)init;
|
||||
- (void)startDisplayLink;
|
||||
- (void)handleDisplayLink:(CADisplayLink *)displayLink;
|
||||
- (void)stopDisplayLink;
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
#import "ViewController.h"
|
||||
#import "UIFloatPanel.h"
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
static ViewController* g_pIOSMainViewController = nil;
|
||||
//------------------------------------------------------------------------------
|
||||
+(ViewController*)GetIOSViewController
|
||||
{
|
||||
return g_pIOSMainViewController;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
-(id)init
|
||||
{
|
||||
self = [super init];
|
||||
if( self != nil )
|
||||
{
|
||||
g_pIOSMainViewController = self;
|
||||
return self;
|
||||
}
|
||||
return Nil;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
//保持屏幕常亮,可以通过脚本设置
|
||||
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
|
||||
self->m_pGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
|
||||
if (self->m_pGLContext)
|
||||
{
|
||||
NSLog(@"iOS OpenGL ES 3.0 context created");
|
||||
}
|
||||
else
|
||||
{
|
||||
self->m_pGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
||||
if (self->m_pGLContext)
|
||||
{
|
||||
NSLog(@"iOS OpenGL ES 2.0 context created");
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"iOS OpenGL ES 2.0 context created failed");
|
||||
}
|
||||
}
|
||||
m_pGLKView = (GLKView *)self.view;
|
||||
m_pGLKView.context = self->m_pGLContext;
|
||||
m_pGLKView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
|
||||
m_pGLKView.drawableStencilFormat = GLKViewDrawableStencilFormat8;
|
||||
[EAGLContext setCurrentContext:self->m_pGLContext];
|
||||
self.preferredFramesPerSecond = 10000;
|
||||
|
||||
//conchRuntime 初始化ConchRuntime引擎
|
||||
m_pConchRuntime = [[conchRuntime alloc]initWithView:m_pGLKView EAGLContext:m_pGLContext downloadThreadNum:3];
|
||||
[self prefersStatusBarHidden];
|
||||
[self setNeedsStatusBarAppearanceUpdate];
|
||||
|
||||
|
||||
//在主线程开这个DisplayLink会导致卡死。因为gl等待会导致事件函数无法调到。
|
||||
m_displayLink=nullptr;
|
||||
//[self startDisplayLink];
|
||||
|
||||
m_floatPanel = [[UIFloatPanel alloc] initWithParentView:m_pGLKView];
|
||||
m_floatPanel.hidden = true;
|
||||
}
|
||||
|
||||
- (void)startDisplayLink
|
||||
{
|
||||
m_displayLink = [CADisplayLink displayLinkWithTarget:self
|
||||
selector:@selector(handleDisplayLink:)];
|
||||
[m_displayLink addToRunLoop:[NSRunLoop currentRunLoop]
|
||||
forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)handleDisplayLink:(CADisplayLink *)displayLink
|
||||
{
|
||||
if( m_pConchRuntime){
|
||||
[m_pConchRuntime onVsync:displayLink.timestamp*1000.0];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopDisplayLink
|
||||
{
|
||||
if(m_displayLink)
|
||||
[m_displayLink invalidate];
|
||||
m_displayLink = nil;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
- (void)dealloc
|
||||
{
|
||||
[m_pConchRuntime destory];
|
||||
[self tearDownGL];
|
||||
if ( [EAGLContext currentContext] == self->m_pGLContext )
|
||||
{
|
||||
[EAGLContext setCurrentContext:nil];
|
||||
}
|
||||
[self stopDisplayLink];
|
||||
m_floatPanel = nil;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
|
||||
//conchRuntime 内存警告的时候的处理
|
||||
[m_pConchRuntime didReceiveMemoryWarning];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
- (void)tearDownGL
|
||||
{
|
||||
[EAGLContext setCurrentContext:self->m_pGLContext];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
- (void)update
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
|
||||
{
|
||||
//conchRuntime renderFrame
|
||||
[m_pConchRuntime renderFrame];
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
//conchRuntime touch
|
||||
[m_pConchRuntime touchesBegan:touches withEvent:event];
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
//conchRuntime touch
|
||||
[m_pConchRuntime touchesMoved:touches withEvent:event];
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
//conchRuntime touch
|
||||
[m_pConchRuntime touchesEnded:touches withEvent:event];
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
//conchRuntime touch
|
||||
[m_pConchRuntime touchesCancelled:touches withEvent:event];
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
-(NSUInteger)supportedInterfaceOrientations
|
||||
{
|
||||
/*
|
||||
UIInterfaceOrientationMaskPortrait, ===2
|
||||
UIInterfaceOrientationMaskPortraitUpsideDown, ===4
|
||||
UIInterfaceOrientationMaskLandscapeLeft, ===8
|
||||
UIInterfaceOrientationMaskLandscapeRight, ===16
|
||||
*/
|
||||
return [conchConfig GetInstance]->m_nOrientationType;
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
- (BOOL)shouldAutorotate
|
||||
{
|
||||
return YES;//支持转屏
|
||||
}
|
||||
- (BOOL)prefersStatusBarHidden
|
||||
{
|
||||
return YES;//隐藏为YES,显示为NO
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <StoreKit/StoreKit.h>
|
||||
|
||||
@protocol JCIapProcessCtrlDelegate <NSObject>
|
||||
@required
|
||||
- (void)onSuccess:(NSString *)p_pProductionIdentifier quantity:(NSInteger)p_iNumber orderID:(NSString *)p_pszOrderID;
|
||||
- (void)onFailed:(NSString *)p_pProductionIdentifier quantity:(NSInteger)p_iNumber orderID:(NSString *)p_pszOrderID;
|
||||
@end
|
||||
|
||||
@interface IAPManager : NSObject<SKProductsRequestDelegate,SKPaymentTransactionObserver>
|
||||
+ (IAPManager*) getInstance;
|
||||
-(void)CZ:(NSString*) jsonParam;
|
||||
- (id)initWithGameID:(NSString*)gameID andDelegate:(id<JCIapProcessCtrlDelegate>)delegate;
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
#import "IAPManager.h"
|
||||
#define __MAX_GAME_ID_SIZE 32
|
||||
|
||||
typedef void (^IAPProductsResponseBlock)(SKProductsRequest* request , SKProductsResponse* response);
|
||||
typedef void (^IAPcheckReceiptCompleteResponseBlock)(NSString* response,NSError* error);
|
||||
|
||||
@interface IAPManager()<NSURLConnectionDataDelegate>
|
||||
@property (nonatomic,copy) IAPProductsResponseBlock requestProductsBlock;
|
||||
@property (nonatomic,copy) IAPcheckReceiptCompleteResponseBlock checkReceiptCompleteBlock;
|
||||
@property (nonatomic,assign) id<JCIapProcessCtrlDelegate> delegate;
|
||||
@property (nonatomic,strong) NSString* gameAppID;
|
||||
@property (nonatomic,strong) SKProductsRequest *request;
|
||||
@property (nonatomic,strong) NSString *strPlateform;
|
||||
@property (nonatomic,assign) BOOL isProcessing;
|
||||
@property (nonatomic,strong) NSMutableData* receiptRequestData;
|
||||
@end
|
||||
|
||||
|
||||
@implementation IAPManager
|
||||
|
||||
+ (IAPManager*) getInstance{
|
||||
static IAPManager* iap = nil;
|
||||
if (iap == nil){
|
||||
iap = [IAPManager alloc];
|
||||
}
|
||||
return iap;
|
||||
}
|
||||
|
||||
- (id)initWithGameID:(NSString*)gameID andDelegate:(id<JCIapProcessCtrlDelegate>)delegate{
|
||||
if ((self = [super init])) {
|
||||
NSAssert(gameID != nil,@"[IAP] gameID can not be nil");
|
||||
NSAssert(gameID.length <= __MAX_GAME_ID_SIZE,@"gameID is too long");
|
||||
self.gameAppID = [NSString stringWithString:gameID];
|
||||
NSAssert(delegate != nil, @"[IAP] delegate can not be nil");
|
||||
self.delegate = delegate;
|
||||
self.strPlateform = [NSString stringWithFormat:@"%@,%@,%@", [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemName],[[UIDevice currentDevice] systemVersion]];
|
||||
NSLog(@"[IAP]plateform info: %@\n", self.strPlateform);
|
||||
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
|
||||
self.isProcessing = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
|
||||
}
|
||||
|
||||
- (void)requestProducts:(NSSet *)productIdentifiers onCompletion:(IAPProductsResponseBlock)completion {
|
||||
self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
|
||||
self.request.delegate = self;
|
||||
self.requestProductsBlock = completion;
|
||||
[self.request start];
|
||||
|
||||
}
|
||||
|
||||
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
|
||||
self.request = nil;
|
||||
if(self.requestProductsBlock) {
|
||||
self.requestProductsBlock (request,response);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
|
||||
NSLog(@"[IAP] SKPaymentTransactionStatePurchased");
|
||||
[self doVerifyTransaction:transaction];
|
||||
}
|
||||
|
||||
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
|
||||
NSLog(@"[IAP] SKPaymentTransactionStateRestored");
|
||||
[self doVerifyTransaction:transaction];
|
||||
}
|
||||
|
||||
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
|
||||
NSLog(@"[IAP] Transaction error: %@ %ld", transaction.error.localizedDescription,(long)transaction.error.code);
|
||||
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
|
||||
NSLog(@"[IAP] SKPaymentTransactionStateFailed");
|
||||
NSMutableDictionary *paymentmulti =(NSMutableDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:transaction.payment.requestData];
|
||||
NSString* _order_id = [paymentmulti objectForKey:@"order_id"];
|
||||
self.isProcessing = NO;
|
||||
[self.delegate onFailed:transaction.payment.productIdentifier quantity:transaction.payment.quantity orderID:_order_id];
|
||||
}
|
||||
|
||||
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
|
||||
{
|
||||
for (SKPaymentTransaction *transaction in transactions)
|
||||
{
|
||||
switch (transaction.transactionState)
|
||||
{
|
||||
case SKPaymentTransactionStatePurchased:
|
||||
[self completeTransaction:transaction];
|
||||
break;
|
||||
case SKPaymentTransactionStateFailed:
|
||||
[self failedTransaction:transaction];
|
||||
break;
|
||||
case SKPaymentTransactionStateRestored:
|
||||
[self restoreTransaction:transaction];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
-(void)CZ:(NSString*) jsonParam
|
||||
{
|
||||
if (self.isProcessing == YES){
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] another payments is processing!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
self.isProcessing = YES;
|
||||
|
||||
|
||||
NSLog(@"[IAP] this is MarketAppStore method pay param=%@",jsonParam);
|
||||
if(jsonParam==NULL)
|
||||
{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] recharge param is nil!\n");
|
||||
[self.delegate onFailed:@"nill" quantity:0 orderID:@"nill"];
|
||||
return;
|
||||
}
|
||||
NSData* pJsonData = [jsonParam dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError* pError;
|
||||
NSDictionary* pJson = [NSJSONSerialization JSONObjectWithData:pJsonData options:kNilOptions error:&pError];
|
||||
if( !pError )
|
||||
{
|
||||
NSString* sProductID = [pJson objectForKey:@"product_id"];
|
||||
int nNum = [[pJson objectForKey:@"amount"] intValue];
|
||||
NSString* sOrderID = [pJson objectForKey:@"order_id"];
|
||||
NSString* sCallbackURL = [pJson objectForKey:@"callback_uri"];
|
||||
NSLog(@"[IAP] buyProps: product_id=%@, amount=%d, order_id=%@,callbackurl=%@",sProductID, nNum, sOrderID,sCallbackURL );
|
||||
|
||||
if( nNum <= 0 || nil == sProductID || nil == sOrderID || nil == sCallbackURL)
|
||||
{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] param error!\n");
|
||||
[self.delegate onFailed:sProductID quantity:nNum orderID:sOrderID];
|
||||
return;
|
||||
}
|
||||
|
||||
if([SKPaymentQueue canMakePayments] == NO)
|
||||
{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] can not make payments!\n");
|
||||
[self.delegate onFailed:sProductID quantity:nNum orderID:sOrderID];
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;
|
||||
if (transactions.count > 0)
|
||||
{
|
||||
//检测是否有未完成的交易
|
||||
SKPaymentTransaction* transaction = [transactions firstObject];
|
||||
if (transaction.transactionState == SKPaymentTransactionStatePurchased)
|
||||
{
|
||||
NSLog(@"[IAP] process uncompleteed transaction");
|
||||
[self doVerifyTransaction:transaction];
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"[IAP] 开始向苹果请求产品信息");
|
||||
[self requestProducts:[[NSSet alloc] initWithObjects:sProductID, nil] onCompletion:^(SKProductsRequest* request,SKProductsResponse* response)
|
||||
{
|
||||
NSLog(@"[IAP] 苹果返回产品信息。");
|
||||
if(response.products.count > 0 ) {
|
||||
|
||||
SKProduct* product =response.products[0];
|
||||
NSMutableString *resOutput = [[NSMutableString alloc] init];
|
||||
[resOutput appendString:@"[IAP] IAP Response Info\n"];
|
||||
[resOutput appendFormat:@"%@,%@,%@,%@,%@\n",
|
||||
product.localizedTitle, // 本地化标题
|
||||
product.localizedDescription, // 本地化描述
|
||||
product.price, // 价格
|
||||
product.priceLocale, // 地域
|
||||
product.productIdentifier]; // 产品标识符
|
||||
NSLog(@"%@",resOutput);
|
||||
|
||||
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
|
||||
|
||||
|
||||
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
|
||||
[dict setObject:sOrderID forKey:@"order_id"];
|
||||
[dict setObject:sCallbackURL forKey:@"backurl"];
|
||||
[dict setObject:self.gameAppID forKey:@"gameid"];
|
||||
NSData* pData = [NSKeyedArchiver archivedDataWithRootObject:dict];
|
||||
|
||||
payment.requestData = pData;
|
||||
payment.quantity = nNum;
|
||||
|
||||
[[SKPaymentQueue defaultQueue] addPayment:payment];
|
||||
}
|
||||
else{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] invalid product!\n");
|
||||
[self.delegate onFailed:sProductID quantity:nNum orderID:sOrderID];
|
||||
}
|
||||
// 错误的产品 ID 回馈
|
||||
NSMutableString *resOutput = [[NSMutableString alloc] init];
|
||||
for( NSString *invalidProductId in response.invalidProductIdentifiers )
|
||||
{
|
||||
[resOutput appendFormat:@"[IAP] Invalid product id: %@\n",invalidProductId];
|
||||
}
|
||||
NSLog(@"%@",resOutput);
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] buyProps:parser json error");
|
||||
[self.delegate onFailed:@"nill" quantity:0 orderID:@"nill"];
|
||||
}
|
||||
}
|
||||
|
||||
// 向验证服务器发起验证请求
|
||||
- (void)doVerifyTransaction: (SKPaymentTransaction *)transaction
|
||||
{
|
||||
if (transaction == nil)
|
||||
return;
|
||||
|
||||
|
||||
if(NULL==transaction.payment.requestData)
|
||||
{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] transDoVerifyTransaction requestData is null");
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
|
||||
[self.delegate onFailed:@"nill" quantity:0 orderID:@"nill"];
|
||||
return;
|
||||
}
|
||||
NSMutableDictionary *paymentmulti =(NSMutableDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:transaction.payment.requestData];//
|
||||
NSString* _order_id = [paymentmulti objectForKey:@"order_id"];
|
||||
NSString* _backurl = [paymentmulti objectForKey:@"backurl"];
|
||||
NSString* _gameid = [paymentmulti objectForKey:@"gameid"];
|
||||
NSLog(@"[IAP] order:%@backurl:%@gameid:%@",_order_id,_backurl,_gameid);
|
||||
|
||||
NSString* pszBase64 = [transaction.transactionReceipt base64Encoding];
|
||||
if(NULL==_order_id||NULL==_backurl||NULL==_gameid||NULL==self.strPlateform||NULL==transaction.payment.productIdentifier||NULL==transaction.transactionIdentifier)
|
||||
{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] doVerifyTransaction something is NULL");
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
|
||||
[self.delegate onFailed:@"nill" quantity:0 orderID:@"nill"];
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableString *sendParam = [[NSMutableString alloc] init];
|
||||
[sendParam appendFormat:@"plateform=%@",self.strPlateform];
|
||||
[sendParam appendFormat:@"&order-id=%@",_order_id];
|
||||
[sendParam appendFormat:@"&game-id=%@",_gameid];
|
||||
[sendParam appendFormat:@"&production-id=%@",transaction.payment.productIdentifier];
|
||||
[sendParam appendFormat:@"&transaction-id=%@",transaction.transactionIdentifier];
|
||||
[sendParam appendFormat:@"&receipt-data=%@",pszBase64];
|
||||
NSData* data = [sendParam dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSLog(@"[IAP] pruchase backurl = %@",_backurl);
|
||||
NSLog(@"[IAP] pruchase param = %@",sendParam);
|
||||
|
||||
NSInteger amount = transaction.payment.quantity;
|
||||
[self checkReceipt:_backurl withData:data onCompletion:^(NSString* response,NSError* error){
|
||||
if (error == nil){
|
||||
|
||||
NSLog(@"[IAP] web result = %@",response);
|
||||
NSData* pJsonData = [response dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError* pError;
|
||||
NSDictionary* pJson = [NSJSONSerialization JSONObjectWithData:pJsonData options:kNilOptions error:&pError];
|
||||
if( !pError ){
|
||||
NSString* resultCode = [pJson objectForKey:@"error-code"];
|
||||
int nCode = [resultCode intValue];
|
||||
if (nCode == 0){
|
||||
NSLog(@"[IAP] verify success!");
|
||||
self.isProcessing = NO;
|
||||
[self.delegate onSuccess:transaction.payment.productIdentifier quantity:amount orderID:_order_id];
|
||||
|
||||
}
|
||||
else{
|
||||
NSLog(@"[IAP] verify err code = %@ info = %@",resultCode,[pJson objectForKey:@"error-info"]);
|
||||
self.isProcessing = NO;
|
||||
[self.delegate onFailed:transaction.payment.productIdentifier quantity:amount orderID:_order_id];
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
self.isProcessing = NO;
|
||||
NSLog(@"[IAP] An error happened while serializing the JSON data.");
|
||||
[self.delegate onFailed:transaction.payment.productIdentifier quantity:amount orderID:_order_id];
|
||||
}
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
|
||||
}
|
||||
else{
|
||||
self.isProcessing = NO;
|
||||
[self.delegate onFailed:transaction.payment.productIdentifier quantity:amount orderID:_order_id];
|
||||
}
|
||||
}];
|
||||
}
|
||||
- (void)checkReceipt:(NSString*)url withData:(NSData*)receiptData onCompletion:(IAPcheckReceiptCompleteResponseBlock)completion
|
||||
{
|
||||
self.checkReceiptCompleteBlock = completion;
|
||||
NSURL* requestURL = [NSURL URLWithString:url];
|
||||
NSMutableURLRequest* req = [[NSMutableURLRequest alloc] initWithURL:requestURL];
|
||||
[req setHTTPMethod:@"POST"];
|
||||
[req setHTTPBody:receiptData];
|
||||
|
||||
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
|
||||
if(conn) {
|
||||
self.receiptRequestData = [[NSMutableData alloc] init];
|
||||
} else {
|
||||
NSError* error = nil;
|
||||
NSMutableDictionary* errorDetail = [[NSMutableDictionary alloc] init];
|
||||
[errorDetail setValue:@"Can't create connection" forKey:NSLocalizedDescriptionKey];
|
||||
error = [NSError errorWithDomain:@"IAPManagerError" code:100 userInfo:errorDetail];
|
||||
if(self.checkReceiptCompleteBlock) {
|
||||
self.checkReceiptCompleteBlock(nil,error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
NSLog(@"[IAP] Cannot transmit receipt data. %@",[error localizedDescription]);
|
||||
if(self.checkReceiptCompleteBlock) {
|
||||
self.checkReceiptCompleteBlock(nil,error);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
[self.receiptRequestData setLength:0];
|
||||
}
|
||||
|
||||
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
[self.receiptRequestData appendData:data];
|
||||
}
|
||||
|
||||
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
NSString *response = [[NSString alloc] initWithData:self.receiptRequestData encoding:NSUTF8StringEncoding];
|
||||
if(self.checkReceiptCompleteBlock) {
|
||||
self.checkReceiptCompleteBlock(response,nil);
|
||||
}
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// main.m
|
||||
// LayaBox
|
||||
//
|
||||
// Created by LayaBox on 3/7/16.
|
||||
// Copyright © 2016 LayaBox. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||