project init

This commit is contained in:
zhl 2021-07-22 15:06:35 +08:00
commit 7a5a2445f7
64 changed files with 2212 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
assets/game
.DS_Store
/platform.js

244
doc/README_IOS.md Normal file
View File

@ -0,0 +1,244 @@
# 项目发布设置使用说明
---
此文档旨在帮助用户顺利的完成项目打包发布,解决发布过程中可能遇到的问题,并最终完成发布工程的个性化配置和功能接入,文档分为以下几个部分:
> * 发布设置前的准备工作
> * 项目发布配置
> * 发布工程的个性化配置
> * JS和原生的通信接入
> * 运行时error事件和state事件处理方法
> * 添加loading界面
---
## 发布设置前的准备工作
- 安装最新版本的launcher
- 确认引擎版本
- 下载的引擎版本必须为***5.1.6及以上***
- 在launcher中的引擎页选择下载
- 安装Xcode
- 建议版本: 8.3或以上
- 后续需要在Xcode中完成发布项目的修改和功能接入
---
## 项目发布配置
### 1. 创建项目
- launcher项目页中点击创建项目填入项目名称并选择引擎版本为5.1.6(或以上),点击创建按钮。
>此文档不涉及具体项目功能,可以关闭 Egret Wing窗口。
### 2. 发布配置
- 在launcher的项目页中找到新创建的项目点击该项目下的发布设置按钮。
![](images/publish_btn.png)
- 点击左侧的iOS按钮然后在右侧页面中输入应用名称填写新的应用包名点击确定。
- 新弹出的窗口中选择点击***打开文件夹***按钮。
---
## 发布工程的个性化配置
- 解决国行手机首次启动需要请求网络权限的问题
- 模版中通过`[_native setNetworkStatusChangeCallback:]`监听网络状态,有网络连接时才启动游戏。
- 访问相册权限的问题
- 为了支持保存截图到本地的功能模版中默认注册了访问相册的权限如不需要可以从info.plist中删除。
- 模版中默认加入的权限并无对应的文字若要发布至AppStore中必须在权限后添加任意提醒用户的文字才能通过审核如“允许Egret Native访问您的相册
![](images/info-plist.jpg)
> - Privacy - Photo Library Usage Description是IOS11.0版本之前的相册读写权限
> - Privacy - Photo Library Additions Usage Description是IOS11.0版本之后的相册写权限,读权限系统已经默认开放
- 没加文字之前与添加文字之后
![](images/PhotoAlbumPrivacy.png) ![](images/PhotoAdditionPrivacy.png)
![](images/PhotoAlbumPrivacyWithString.png) ![](images/PhotoAdditionPrivacyWithString.png)
- 个性化设置
- 修改游戏地址:将函数`[native startGame:]`的参数替换为当前游戏的地址。
>需要注意如果工程的assets目录下存在game文件那么此处填写的游戏必须和game文件中的游戏保持一致否则会出现问题。
- 控制FPS面板的显示修改`_native.config.showFPS = true/false;`。true为显示false为隐藏。
- 控制log在屏幕上的显示时间修改`_native.config.fpsLogTime = 30;`,改为`-1`时是永久显示。
- 是否禁用核心渲染驱动:修改`_native.config.disableNativeRender = false/true`。false为启用核心渲染驱动true为禁用核心渲染驱动。
- 是否清理缓存:修改`_native.config.clearCache = false/true;`。false为不自动清理缓存true为自动清理缓存。
- 控制页面超时时间:修改`_native.config.loadingTimeout = 0;`。单位为秒0为不设置超时。
- 游戏是否支持刘海屏显示:修改`_native.config.useCutout = false;`。true 为游戏支持并适配false为不支持。
---
## JS和原生的通信接入
### 1. 原生部分
- 在AppDelegate.mm的`setExternalInterfaces`方法里配置通信接口
- `[_native setExternalInterface: Callback:]` 注册JS中可以调用的原生函数
- `[_native callExternalInterface: Value:]`调用JS函数
- `setExternalInterface`方法的第一个参数是JS中调用原生函数的函数名第二个参数是该原生函数的功能实现
- `callExternalInterface`方法的第一个参数是JS函数的函数名第二个传入的参数
```objective-c
- (void)setExternalInterfaces {
__block EgretNativeIOS* support = _native;
[_native setExternalInterface:@"sendToNative" Callback:^(NSString* message) {
NSString* str = @"Native get message: ";
str = [str stringByAppendingString:message];
NSLog(@"%@", str);
[support callExternalInterface:@"sendToJS" Value:str];
}];
}
```
### 2. JS部分
- `egret.ExternalInterface.call`调用注册过的原生函数
```js
egret.ExternalInterface.call("sendToNative", "message from JS");
```
- `egret.ExternalInterface.addCallback`注册原生中可以调用的JS函数
```js
function sendToJS(msg) {
console.log(msg);
}
egret.ExternalInterface.addCallback("sendToJS", sendToJS);
```
> 只有通过`setExternalInterface`注册的原生函数才能在JS中通过`call`调用。
> 只有通过`addCallback`注册的JS函数才能在原生中通过`callExternalInterface`调用。
---
## runtime阶段状态定义
- 我们将runtime启动及运行的阶段进行了定义主要分为如下几种阶段状态
> * loading: 系统初始时的默认状态
> * starting: 表示index.html已经加载成功
> * running: 表示starting状态后执行完json、js等文件资源加载并开始执行渲染
## 运行时state事件处理方法
### 1. runtime运行中各个事件的说明
- 事件说明如下
|事件类型 |事件消息 |所属阶段 |事件意义 |
|:-------------|----------------------------|:-----------------|:-----------------------------------------------------------------------------------------|
|@onState |{"state”:”starting”} |loading到starting |index.html加载成功 |
|@onState |{"state”:”running”} |starting到running |starting状态后开始执行渲染(注starting状态后若json或js等文件加载失败会通过具体的js错误进行提示) |
### 2. 监听state事件的方法
- 注册对state事件的监听在函数`setExternalInterfaces`中:
```objective-c
- (void)setExternalInterfaces {
__block EgretNativeIOS* support = _native;
__block AppDelegate* thiz = self;
[_native setExternalInterface:@"@onState" Callback:^(NSString* message) {
NSData* jsonData = [message dataUsingEncoding:NSUTF8StringEncoding];
NSError* err;
NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&err];
if (err) {
NSLog(@"onState message failed to analyze");
return;
}
NSString* state = [dic objectForKey:@"state"];
if ([state isEqualToString:@"starting"]) {// 正在启动引擎
NSLog(@"Engine starting");
} else if ([state isEqualToString:@"running"]) {// 引擎开始渲染
// 如果您使用了自定义闪屏,这里是关掉的好时机
NSLog(@"Engine is rendering");
}
NSLog(@"Native get onState message: %@", state);
}];
}
```
---
## 处理错误
如果您需要处理错误,请参照 [Egret Native 上处理游戏错误](https://docs.egret.com/native/docs/manual/abouterrors)。
---
## 添加loading界面
>loading界面的使用依赖与state事件的处理请先完成上一部分的阅读。
### 1. 打开loading界面
- 在AppDelegate的didFinishLaunchingWithOptions函数中调用函数showLoadingView
```objective-c
@implementation AppDelegate {
UIViewController* _viewController;
UIImageView* _imageView;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSString* gameUrl = @"http://tool.egret-labs.org/Weiduan/game/index.html";
_native = [[EgretNativeIOS alloc] init];
_native.config.showFPS = true;
_native.config.fpsLogTime = 30;
_native.config.disableNativeRender = false;
_native.config.clearCache = false;
_viewController = [[ViewController alloc] initWithEAGLView:[_native createEAGLView]];
if (![_native initWithViewController:_viewController]) {
return false;
}
[self setExternalInterfaces];
NSString* networkState = [_native getNetworkState];
if ([networkState isEqualToString:@"NotReachable"]) {
__block EgretNativeIOS* native = _native;
[_native setNetworkStatusChangeCallback:^(NSString* state) {
if (![state isEqualToString:@"NotReachable"]) {
dispatch_async(dispatch_get_main_queue(), ^{
[native startGame:gameUrl];
});
}
}];
return true;
}
[_native startGame:gameUrl];
[self showLoadingView];
return true;
}
- (void)showLoadingView {
_imageView = [[UIImageView alloc] initWithFrame:_viewController.view.frame];
[_imageView setImage:[UIImage imageNamed:@"icon"]];
[_viewController.view addSubview:_imageView];
[_viewController.view bringSubviewToFront:_imageView];
}
```
### 2. 关闭loading界面
- 收到{"state”:”running”}消息后调用函数hideLoadingView
```objective-c
- (void)hideLoadingView {
[_imageView removeFromSuperview];
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
doc/images/info-plist.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

BIN
doc/images/publish_btn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,45 @@
// Copyright (C) Egret Technology. All rights reserved.
// EgretRuntimeVersion: 1.1.2
// EgretRuntimeBuild: 24082931
#import <UIKit/UIKit.h>
@interface EgretNativeConfig : NSObject
@property (nonatomic) bool showFPS;
@property (nonatomic) int fpsLogTime;
@property (nonatomic) bool disableNativeRender;
@property (nonatomic) bool enableGLBatch;
@property (nonatomic) bool clearCache;
@property (nonatomic) unsigned long loadingTimeout;
@property (nonatomic) bool transparentGameView;
@property (nonatomic) NSString* preloadPath;
@property (nonatomic) bool useCutout;
@end
@interface EgretNativeIOS : NSObject
- (instancetype)init;
- (UIView*)createEAGLView;
- (bool)initWithViewController:(UIViewController*)viewController;
- (UIViewController*)getRootViewController;
- (NSString*)getRuntimeVersion;
- (void)setOption:(NSString*)value forKey:(NSString*)key;
- (void)startGame:(NSString*)gameUrl;
- (void)pause;
- (void)resume;
- (void)setExternalInterface:(NSString*)funcName Callback:(void(^)(NSString*))callback;
- (void)callExternalInterface:(NSString*)funcName Value:(NSString*)value;
- (void)setFPSBoardEnable:(bool)enable;
- (NSString*)getNetworkState;
- (void)setNetworkStatusChangeCallback:(void(^)(NSString*))callback;
- (void)destroy;
@property (nonatomic, strong) UIWindow* window;
@property (nonatomic, readonly, strong) EgretNativeConfig* config;
@end

Binary file not shown.

View File

@ -0,0 +1,503 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
305DF7A3200D95C5008022B6 /* game in Resources */ = {isa = PBXBuildFile; fileRef = 305DF7A2200D95C5008022B6 /* game */; };
306A7A98200C83F500E1EBB6 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 306A7A97200C83F500E1EBB6 /* ViewController.mm */; };
306A7A9D200C83F500E1EBB6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 306A7A9C200C83F500E1EBB6 /* Assets.xcassets */; };
306A7AAB200C88E500E1EBB6 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7AAA200C88E500E1EBB6 /* AVFoundation.framework */; };
306A7AAD200C88EA00E1EBB6 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7AAC200C88EA00E1EBB6 /* AudioToolbox.framework */; };
306A7AAF200C88F600E1EBB6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7AAE200C88F600E1EBB6 /* Foundation.framework */; };
306A7AB1200C890300E1EBB6 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7AB0200C890300E1EBB6 /* OpenAL.framework */; };
306A7AB3200C890E00E1EBB6 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7AB2200C890E00E1EBB6 /* SystemConfiguration.framework */; };
306A7AB5200C891B00E1EBB6 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7AB4200C891B00E1EBB6 /* libz.tbd */; };
306A7AB7200C892500E1EBB6 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7AB6200C892500E1EBB6 /* libiconv.tbd */; };
306A7ABB200C898400E1EBB6 /* libicucore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7ABA200C898400E1EBB6 /* libicucore.tbd */; };
306A7ABD200C89B900E1EBB6 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7ABC200C89B900E1EBB6 /* JavaScriptCore.framework */; };
306A7ABF200C89C000E1EBB6 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 306A7ABE200C89C000E1EBB6 /* OpenGLES.framework */; };
3077067820215DF200548664 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3077067720215DF200548664 /* MediaPlayer.framework */; };
3077067A20215DF600548664 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3077067920215DF600548664 /* libsqlite3.tbd */; };
307B49CF2059046B003D64E0 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 307B49CE2059046B003D64E0 /* AdSupport.framework */; };
30E559EA200F1DE2001C0B78 /* libEgretNativeIOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 30E559E9200F1DE2001C0B78 /* libEgretNativeIOS.a */; };
B34149E425F23387008BDFF8 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B34149E325F23387008BDFF8 /* CoreMotion.framework */; };
B34149E625F23392008BDFF8 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B34149E525F23392008BDFF8 /* CoreLocation.framework */; };
D5FF442F26A80E5F00CF155C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FF442E26A80E5F00CF155C /* AppDelegate.swift */; };
D5FF443126A80F8600CF155C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FF443026A80F8600CF155C /* ViewController.swift */; };
D5FF443326A80FA600CF155C /* m_loading.jpg in Resources */ = {isa = PBXBuildFile; fileRef = D5FF443226A80FA600CF155C /* m_loading.jpg */; };
D5FF444E26A80FF600CF155C /* IDUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FF444D26A80FF600CF155C /* IDUtil.swift */; };
D5FF445026A80FFB00CF155C /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FF444F26A80FFB00CF155C /* KeychainPasswordItem.swift */; };
D5FF445426A948F600CF155C /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5FF445326A948F500CF155C /* StoreKit.framework */; };
D5FF445726A94B8500CF155C /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = D5FF445626A94B8500CF155C /* SwiftyJSON */; };
ED50D6502436EB69005B9E1E /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED50D64F2436EB69005B9E1E /* CoreMedia.framework */; };
ED50D6522436EB70005B9E1E /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED50D6512436EB70005B9E1E /* AVKit.framework */; };
ED9FBC2E21830D2A005A5DF0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED9FBC2D21830D2A005A5DF0 /* UIKit.framework */; };
ED9FBC3021830D50005A5DF0 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED9FBC2F21830D50005A5DF0 /* CoreText.framework */; };
ED9FBC3221830D63005A5DF0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED9FBC3121830D63005A5DF0 /* CoreGraphics.framework */; };
EDF3B7E524580A4B009DFBBD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EDF3B7E424580A4B009DFBBD /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
305DF7A2200D95C5008022B6 /* game */ = {isa = PBXFileReference; lastKnownFileType = folder; name = game; path = assets/game; sourceTree = "<group>"; };
306A7A8D200C83F500E1EBB6 /* 武极天下.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "武极天下.app"; sourceTree = BUILT_PRODUCTS_DIR; };
306A7A96200C83F500E1EBB6 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
306A7A97200C83F500E1EBB6 /* ViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewController.mm; sourceTree = "<group>"; };
306A7A9C200C83F500E1EBB6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
306A7AA1200C83F500E1EBB6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
306A7AAA200C88E500E1EBB6 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
306A7AAC200C88EA00E1EBB6 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
306A7AAE200C88F600E1EBB6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
306A7AB0200C890300E1EBB6 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
306A7AB2200C890E00E1EBB6 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
306A7AB4200C891B00E1EBB6 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
306A7AB6200C892500E1EBB6 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; };
306A7AB8200C896F00E1EBB6 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
306A7ABA200C898400E1EBB6 /* libicucore.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libicucore.tbd; path = usr/lib/libicucore.tbd; sourceTree = SDKROOT; };
306A7ABC200C89B900E1EBB6 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
306A7ABE200C89C000E1EBB6 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
3077067720215DF200548664 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
3077067920215DF600548664 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
307B49CE2059046B003D64E0 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; };
30E559E9200F1DE2001C0B78 /* libEgretNativeIOS.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libEgretNativeIOS.a; path = "egret-libs/libEgretNativeIOS.a"; sourceTree = "<group>"; };
84860E512179DA92001FCEE7 /* README_IOS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README_IOS.md; sourceTree = "<group>"; };
B34149E325F23387008BDFF8 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
B34149E525F23392008BDFF8 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
D5FF442D26A80E5E00CF155C /* wjtx-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "wjtx-Bridging-Header.h"; sourceTree = "<group>"; };
D5FF442E26A80E5F00CF155C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
D5FF443026A80F8600CF155C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
D5FF443226A80FA600CF155C /* m_loading.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = m_loading.jpg; sourceTree = "<group>"; };
D5FF444D26A80FF600CF155C /* IDUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IDUtil.swift; sourceTree = "<group>"; };
D5FF444F26A80FFB00CF155C /* KeychainPasswordItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainPasswordItem.swift; sourceTree = "<group>"; };
D5FF445226A832BE00CF155C /* 武极天下.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = "武极天下.entitlements"; path = "../武极天下.entitlements"; sourceTree = "<group>"; };
D5FF445326A948F500CF155C /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
ED50D64F2436EB69005B9E1E /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
ED50D6512436EB70005B9E1E /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
ED9FBC2D21830D2A005A5DF0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
ED9FBC2F21830D50005A5DF0 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
ED9FBC3121830D63005A5DF0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
EDF3B7E424580A4B009DFBBD /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
306A7A8A200C83F500E1EBB6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B34149E625F23392008BDFF8 /* CoreLocation.framework in Frameworks */,
B34149E425F23387008BDFF8 /* CoreMotion.framework in Frameworks */,
D5FF445726A94B8500CF155C /* SwiftyJSON in Frameworks */,
ED9FBC3221830D63005A5DF0 /* CoreGraphics.framework in Frameworks */,
ED9FBC3021830D50005A5DF0 /* CoreText.framework in Frameworks */,
ED9FBC2E21830D2A005A5DF0 /* UIKit.framework in Frameworks */,
307B49CF2059046B003D64E0 /* AdSupport.framework in Frameworks */,
30E559EA200F1DE2001C0B78 /* libEgretNativeIOS.a in Frameworks */,
3077067A20215DF600548664 /* libsqlite3.tbd in Frameworks */,
3077067820215DF200548664 /* MediaPlayer.framework in Frameworks */,
306A7ABF200C89C000E1EBB6 /* OpenGLES.framework in Frameworks */,
306A7ABD200C89B900E1EBB6 /* JavaScriptCore.framework in Frameworks */,
306A7ABB200C898400E1EBB6 /* libicucore.tbd in Frameworks */,
306A7AB7200C892500E1EBB6 /* libiconv.tbd in Frameworks */,
306A7AB5200C891B00E1EBB6 /* libz.tbd in Frameworks */,
ED50D6502436EB69005B9E1E /* CoreMedia.framework in Frameworks */,
ED50D6522436EB70005B9E1E /* AVKit.framework in Frameworks */,
306A7AB3200C890E00E1EBB6 /* SystemConfiguration.framework in Frameworks */,
306A7AAF200C88F600E1EBB6 /* Foundation.framework in Frameworks */,
306A7AB1200C890300E1EBB6 /* OpenAL.framework in Frameworks */,
306A7AAD200C88EA00E1EBB6 /* AudioToolbox.framework in Frameworks */,
306A7AAB200C88E500E1EBB6 /* AVFoundation.framework in Frameworks */,
D5FF445426A948F600CF155C /* StoreKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
305DF7A1200D957D008022B6 /* assets */ = {
isa = PBXGroup;
children = (
305DF7A2200D95C5008022B6 /* game */,
);
name = assets;
sourceTree = "<group>";
};
306A7A84200C83F500E1EBB6 = {
isa = PBXGroup;
children = (
84860E502179DA92001FCEE7 /* doc */,
305DF7A1200D957D008022B6 /* assets */,
306A7A8F200C83F500E1EBB6 /* ios-template */,
306A7A8E200C83F500E1EBB6 /* Products */,
306A7AA7200C88C500E1EBB6 /* Frameworks */,
);
sourceTree = "<group>";
};
306A7A8E200C83F500E1EBB6 /* Products */ = {
isa = PBXGroup;
children = (
306A7A8D200C83F500E1EBB6 /* 武极天下.app */,
);
name = Products;
sourceTree = "<group>";
};
306A7A8F200C83F500E1EBB6 /* ios-template */ = {
isa = PBXGroup;
children = (
D5FF445226A832BE00CF155C /* 武极天下.entitlements */,
EDF3B7E424580A4B009DFBBD /* LaunchScreen.storyboard */,
D5FF444D26A80FF600CF155C /* IDUtil.swift */,
D5FF444F26A80FFB00CF155C /* KeychainPasswordItem.swift */,
D5FF442E26A80E5F00CF155C /* AppDelegate.swift */,
306A7A96200C83F500E1EBB6 /* ViewController.h */,
D5FF443026A80F8600CF155C /* ViewController.swift */,
306A7A97200C83F500E1EBB6 /* ViewController.mm */,
D5FF443226A80FA600CF155C /* m_loading.jpg */,
306A7A9C200C83F500E1EBB6 /* Assets.xcassets */,
306A7AA1200C83F500E1EBB6 /* Info.plist */,
306A7A90200C83F500E1EBB6 /* Supporting Files */,
D5FF442D26A80E5E00CF155C /* wjtx-Bridging-Header.h */,
);
path = "ios-template";
sourceTree = "<group>";
};
306A7A90200C83F500E1EBB6 /* Supporting Files */ = {
isa = PBXGroup;
children = (
);
name = "Supporting Files";
sourceTree = "<group>";
};
306A7AA7200C88C500E1EBB6 /* Frameworks */ = {
isa = PBXGroup;
children = (
D5FF445326A948F500CF155C /* StoreKit.framework */,
B34149E525F23392008BDFF8 /* CoreLocation.framework */,
B34149E325F23387008BDFF8 /* CoreMotion.framework */,
ED50D6512436EB70005B9E1E /* AVKit.framework */,
ED50D64F2436EB69005B9E1E /* CoreMedia.framework */,
ED9FBC3121830D63005A5DF0 /* CoreGraphics.framework */,
ED9FBC2F21830D50005A5DF0 /* CoreText.framework */,
ED9FBC2D21830D2A005A5DF0 /* UIKit.framework */,
307B49CE2059046B003D64E0 /* AdSupport.framework */,
3077067920215DF600548664 /* libsqlite3.tbd */,
3077067720215DF200548664 /* MediaPlayer.framework */,
30E559E9200F1DE2001C0B78 /* libEgretNativeIOS.a */,
306A7ABE200C89C000E1EBB6 /* OpenGLES.framework */,
306A7ABC200C89B900E1EBB6 /* JavaScriptCore.framework */,
306A7ABA200C898400E1EBB6 /* libicucore.tbd */,
306A7AB8200C896F00E1EBB6 /* libc++.tbd */,
306A7AB6200C892500E1EBB6 /* libiconv.tbd */,
306A7AB4200C891B00E1EBB6 /* libz.tbd */,
306A7AB2200C890E00E1EBB6 /* SystemConfiguration.framework */,
306A7AB0200C890300E1EBB6 /* OpenAL.framework */,
306A7AAE200C88F600E1EBB6 /* Foundation.framework */,
306A7AAC200C88EA00E1EBB6 /* AudioToolbox.framework */,
306A7AAA200C88E500E1EBB6 /* AVFoundation.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
84860E502179DA92001FCEE7 /* doc */ = {
isa = PBXGroup;
children = (
84860E512179DA92001FCEE7 /* README_IOS.md */,
);
path = doc;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
306A7A8C200C83F500E1EBB6 /* 武极天下 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 306A7AA4200C83F500E1EBB6 /* Build configuration list for PBXNativeTarget "武极天下" */;
buildPhases = (
306A7A89200C83F500E1EBB6 /* Sources */,
306A7A8A200C83F500E1EBB6 /* Frameworks */,
306A7A8B200C83F500E1EBB6 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "武极天下";
packageProductDependencies = (
D5FF445626A94B8500CF155C /* SwiftyJSON */,
);
productName = "武极天下";
productReference = 306A7A8D200C83F500E1EBB6 /* 武极天下.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
306A7A85200C83F500E1EBB6 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1250;
ORGANIZATIONNAME = egret;
TargetAttributes = {
306A7A8C200C83F500E1EBB6 = {
CreatedOnToolsVersion = 8.3.3;
DevelopmentTeam = 299H75LKGK;
LastSwiftMigration = 1250;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 306A7A88200C83F500E1EBB6 /* Build configuration list for PBXProject "ios-template" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 306A7A84200C83F500E1EBB6;
packageReferences = (
D5FF445526A94B8500CF155C /* XCRemoteSwiftPackageReference "SwiftyJSON" */,
);
productRefGroup = 306A7A8E200C83F500E1EBB6 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
306A7A8C200C83F500E1EBB6 /* 武极天下 */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
306A7A8B200C83F500E1EBB6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
305DF7A3200D95C5008022B6 /* game in Resources */,
EDF3B7E524580A4B009DFBBD /* LaunchScreen.storyboard in Resources */,
D5FF443326A80FA600CF155C /* m_loading.jpg in Resources */,
306A7A9D200C83F500E1EBB6 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
306A7A89200C83F500E1EBB6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D5FF445026A80FFB00CF155C /* KeychainPasswordItem.swift in Sources */,
D5FF443126A80F8600CF155C /* ViewController.swift in Sources */,
D5FF442F26A80E5F00CF155C /* AppDelegate.swift in Sources */,
D5FF444E26A80FF600CF155C /* IDUtil.swift in Sources */,
306A7A98200C83F500E1EBB6 /* ViewController.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
306A7AA2200C83F500E1EBB6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
306A7AA3200C83F500E1EBB6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
306A7AA5200C83F500E1EBB6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "武极天下.entitlements";
DEVELOPMENT_TEAM = 299H75LKGK;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/egret-libs/include";
INFOPLIST_FILE = "ios-template/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/egret-libs";
PRODUCT_BUNDLE_IDENTIFIER = com.jc.wjtx;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "ios-template/Wjtx-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
306A7AA6200C83F500E1EBB6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "武极天下.entitlements";
DEVELOPMENT_TEAM = 299H75LKGK;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/egret-libs/include";
INFOPLIST_FILE = "ios-template/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/egret-libs";
PRODUCT_BUNDLE_IDENTIFIER = com.jc.wjtx;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "ios-template/Wjtx-Bridging-Header.h";
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
306A7A88200C83F500E1EBB6 /* Build configuration list for PBXProject "ios-template" */ = {
isa = XCConfigurationList;
buildConfigurations = (
306A7AA2200C83F500E1EBB6 /* Debug */,
306A7AA3200C83F500E1EBB6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
306A7AA4200C83F500E1EBB6 /* Build configuration list for PBXNativeTarget "武极天下" */ = {
isa = XCConfigurationList;
buildConfigurations = (
306A7AA5200C83F500E1EBB6 /* Debug */,
306A7AA6200C83F500E1EBB6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
D5FF445526A94B8500CF155C /* XCRemoteSwiftPackageReference "SwiftyJSON" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SwiftyJSON/SwiftyJSON";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 5.0.1;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
D5FF445626A94B8500CF155C /* SwiftyJSON */ = {
isa = XCSwiftPackageProductDependency;
package = D5FF445526A94B8500CF155C /* XCRemoteSwiftPackageReference "SwiftyJSON" */;
productName = SwiftyJSON;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 306A7A85200C83F500E1EBB6 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,16 @@
{
"object": {
"pins": [
{
"package": "SwiftyJSON",
"repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON",
"state": {
"branch": null,
"revision": "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07",
"version": "5.0.1"
}
}
]
},
"version": 1
}

View File

@ -0,0 +1,35 @@
<?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>SchemeUserState</key>
<dict>
<key>Playground (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>Playground (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
</dict>
<key>Playground (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>武极天下.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@end

View File

@ -0,0 +1,93 @@
#import "AppDelegate.h"
#import "ViewController.h"
#import <EgretNativeIOS.h>
@implementation AppDelegate {
EgretNativeIOS* _native;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSString* gameUrl = @"http://local/game/index.html";
_native = [[EgretNativeIOS alloc] init];
_native.config.showFPS = true;
_native.config.fpsLogTime = 30;
_native.config.disableNativeRender = false;
_native.config.clearCache = false;
_native.config.useCutout = false;
UIViewController* viewController = [[ViewController alloc] initWithEAGLView:[_native createEAGLView]];
if (![_native initWithViewController:viewController]) {
return false;
}
[self setExternalInterfaces];
NSString* networkState = [_native getNetworkState];
if ([networkState isEqualToString:@"NotReachable"]) {
__block EgretNativeIOS* native = _native;
[_native setNetworkStatusChangeCallback:^(NSString* state) {
if (![state isEqualToString:@"NotReachable"]) {
dispatch_async(dispatch_get_main_queue(), ^{
[native startGame:gameUrl];
});
}
}];
return true;
}
[_native startGame:gameUrl];
return true;
}
- (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.
[_native pause];
}
- (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.
[_native resume];
}
- (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:.
// Saves changes in the application's managed object context before the application terminates.
}
- (void)setExternalInterfaces {
__block EgretNativeIOS* support = _native;
[_native setExternalInterface:@"sendToNative" Callback:^(NSString* message) {
NSString* str = [NSString stringWithFormat:@"Native get message: %@", message];
NSLog(@"%@", str);
[support callExternalInterface:@"sendToJS" Value:str];
}];
[_native setExternalInterface:@"@onState" Callback:^(NSString *message) {
NSLog(@"Get @onState: %@", message);
}];
[_native setExternalInterface:@"@onError" Callback:^(NSString *message) {
NSLog(@"Get @onError: %@", message);
}];
[_native setExternalInterface:@"@onJSError" Callback:^(NSString *message) {
NSLog(@"Get @onJSError: %@", message);
}];
}
- (void)dealloc {
[_native destroy];
}
@end

View File

@ -0,0 +1,127 @@
//
// AppDelegate.swift
//
//
// Created by zhl on 2021/7/21.
// Copyright © 2021 egret. All rights reserved.
//
import UIKit
import Foundation
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var _viewController: UIViewController?
var _imageView: UIImageView?
var _native: EgretNativeIOS = EgretNativeIOS.init()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let gameUrl = "http://local/game/index.html"
_native = EgretNativeIOS.init();
_native.config.showFPS = false;
_native.config.fpsLogTime = 30;
_native.config.disableNativeRender = false;
_native.config.clearCache = false;
_native.config.useCutout = false;
_native.config.enableGLBatch = true;
UIApplication.shared.isIdleTimerDisabled = true;
_viewController = ViewController.init(eaglView: _native.createEAGLView());
if (!(_native.initWith(_viewController))) {
return false;
}
self.setExternalInterfaces()
let networkState:String? = _native.getNetworkState();
if (networkState == "NotReachable") {
print(">>>>>>>>>>>>>>>>>>>>no network")
let native = _native;
_native.startGame(gameUrl);
self.showLoadingView();
_native.setNetworkStatusChangeCallback({ (state) in
if (state != "NotReachable") {
DispatchQueue.main.async {
native.startGame(gameUrl)
self.showLoadingView();
}
}
})
return true;
}
_native.startGame(gameUrl);
self.showLoadingView();
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// 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 invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// 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.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// 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.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func setExternalInterfaces() {
let support = _native;
_native.setExternalInterface("sendToNative", callback: { (message) -> () in
var str: String = "";
str.append(message!);
support.callExternalInterface("sendToJS", value: str);
})
_native.setExternalInterface("@onState", callback: { (message) -> () in
print("Get @onStage: %s", message as Any)
})
_native.setExternalInterface("@onError", callback: { (message) -> () in
print("Get @onError: %s", message as Any)
})
_native.setExternalInterface("@onJSError", callback: { (message) -> () in
print("Get @onJSError: %s", message as Any)
})
_native.setExternalInterface("@egretGameStarted", callback: { (message) -> () in
print("Get @egretGameStarted: %s", message as Any)
})
_native.setExternalInterface("getUid", callback: { (message) -> () in
print("Get @getUid: %s", message as Any)
let id = IDUtil.getUid();
let data = String(format:"{\"openid\":\"\", \"token\":\"%@\"}", arguments:[id]);
support.callExternalInterface("sendUidToJS", value: data);
})
_native.setExternalInterface("removeNativeLoading", callback: { (message) -> () in
print("Get @removeNativeLoading: %s", message as Any)
self.hideLoadingView();
})
_native.setExternalInterface("hideLoadImg", callback: { (message) -> () in
print("Get @hideLoadImg: %s", message as Any)
self.hideLoadingView();
})
}
func showLoadingView() {
let image = UIImage(named: "m_loading.jpg");
_imageView = UIImageView(image: image);
_imageView?.contentMode = UIView.ContentMode.scaleAspectFill
_imageView?.frame = _viewController!.view.frame;
_viewController!.view.addSubview(_imageView!);
_viewController!.view.bringSubviewToFront(_imageView!);
}
func hideLoadingView(){
_imageView?.removeFromSuperview();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -0,0 +1,116 @@
{
"images" : [
{
"filename" : "IconSmall-20@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "IconSmall-20@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "IconSmall@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "IconSmall@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "IconSmall-40@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "IconSmall-40@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "Icon@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "Icon@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "IconSmall-20.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "IconSmall-20-iPad@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "IconSmall.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "IconSmall-iPad@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "IconSmall-40.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "IconSmall-40-iPad@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "Icon-76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "Icon-76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "Icon-83.5@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "AppStoreIcon.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

47
ios-template/IDUtil.swift Normal file
View File

@ -0,0 +1,47 @@
//
// IDUtil.swift
//
//
// Created by zhl on 2020/6/17.
// Copyright © 2020 egret. All rights reserved.
//
import UIKit
public class IDUtil: NSObject{
static let serviceName = "Wjtx"
static let accessGroup: String? = nil
static let accountName = "wjtx_uid"
public static func getUid() -> String {
let id = getSavedUid()
if (id != "") {
return id
}
let strIDFV = UIDevice.current.identifierForVendor!.uuidString.lowercased();
saveUid(uid: strIDFV)
return strIDFV;
}
static func saveUid(uid: String) {
do {
let passwordItem = KeychainPasswordItem(service: serviceName, account: accountName, accessGroup: accessGroup)
try passwordItem.savePassword(uid)
} catch {
print("Error updating keychain - \(error)")
}
}
static func getSavedUid() -> String {
do {
let passwordItem = KeychainPasswordItem(service: serviceName, account: accountName, accessGroup: accessGroup)
let password = try passwordItem.readPassword()
return password
} catch {
print("Error reading password from keychain - \(error)")
return ""
}
}
}

50
ios-template/Info.plist Normal file
View File

@ -0,0 +1,50 @@
<?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>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>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSPhotoLibraryAddUsageDescription</key>
<string></string>
<key>NSPhotoLibraryUsageDescription</key>
<string></string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,179 @@
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this samples licensing information
Abstract:
A struct for accessing generic password keychain items.
*/
import Foundation
struct KeychainPasswordItem {
// MARK: Types
enum KeychainError: Error {
case noPassword
case unexpectedPasswordData
case unexpectedItemData
case unhandledError(status: OSStatus)
}
// MARK: Properties
let service: String
private(set) var account: String
let accessGroup: String?
// MARK: Intialization
init(service: String, account: String, accessGroup: String? = nil) {
self.service = service
self.account = account
self.accessGroup = accessGroup
}
// MARK: Keychain access
func readPassword() throws -> String {
/*
Build a query to find the item that matches the service, account and
access group.
*/
var query = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
query[kSecMatchLimit as String] = kSecMatchLimitOne
query[kSecReturnAttributes as String] = kCFBooleanTrue
query[kSecReturnData as String] = kCFBooleanTrue
// Try to fetch the existing keychain item that matches the query.
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
// Check the return status and throw an error if appropriate.
guard status != errSecItemNotFound else { throw KeychainError.noPassword }
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
// Parse the password string from the query result.
guard let existingItem = queryResult as? [String : AnyObject],
let passwordData = existingItem[kSecValueData as String] as? Data,
let password = String(data: passwordData, encoding: String.Encoding.utf8)
else {
throw KeychainError.unexpectedPasswordData
}
return password
}
func savePassword(_ password: String) throws {
// Encode the password into an Data object.
let encodedPassword = password.data(using: String.Encoding.utf8)!
do {
// Check for an existing item in the keychain.
try _ = readPassword()
// Update the existing item with the new password.
var attributesToUpdate = [String : AnyObject]()
attributesToUpdate[kSecValueData as String] = encodedPassword as AnyObject?
let query = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
let status = SecItemUpdate(query as CFDictionary, attributesToUpdate as CFDictionary)
// Throw an error if an unexpected status was returned.
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
}
catch KeychainError.noPassword {
/*
No password was found in the keychain. Create a dictionary to save
as a new keychain item.
*/
var newItem = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
newItem[kSecValueData as String] = encodedPassword as AnyObject?
// Add a the new item to the keychain.
let status = SecItemAdd(newItem as CFDictionary, nil)
// Throw an error if an unexpected status was returned.
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
}
}
mutating func renameAccount(_ newAccountName: String) throws {
// Try to update an existing item with the new account name.
var attributesToUpdate = [String : AnyObject]()
attributesToUpdate[kSecAttrAccount as String] = newAccountName as AnyObject?
let query = KeychainPasswordItem.keychainQuery(withService: service, account: self.account, accessGroup: accessGroup)
let status = SecItemUpdate(query as CFDictionary, attributesToUpdate as CFDictionary)
// Throw an error if an unexpected status was returned.
guard status == noErr || status == errSecItemNotFound else { throw KeychainError.unhandledError(status: status) }
self.account = newAccountName
}
func deleteItem() throws {
// Delete the existing item from the keychain.
let query = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
let status = SecItemDelete(query as CFDictionary)
// Throw an error if an unexpected status was returned.
guard status == noErr || status == errSecItemNotFound else { throw KeychainError.unhandledError(status: status) }
}
static func passwordItems(forService service: String, accessGroup: String? = nil) throws -> [KeychainPasswordItem] {
// Build a query for all items that match the service and access group.
var query = KeychainPasswordItem.keychainQuery(withService: service, accessGroup: accessGroup)
query[kSecMatchLimit as String] = kSecMatchLimitAll
query[kSecReturnAttributes as String] = kCFBooleanTrue
query[kSecReturnData as String] = kCFBooleanFalse
// Fetch matching items from the keychain.
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
// If no items were found, return an empty array.
guard status != errSecItemNotFound else { return [] }
// Throw an error if an unexpected status was returned.
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
// Cast the query result to an array of dictionaries.
guard let resultData = queryResult as? [[String : AnyObject]] else { throw KeychainError.unexpectedItemData }
// Create a `KeychainPasswordItem` for each dictionary in the query result.
var passwordItems = [KeychainPasswordItem]()
for result in resultData {
guard let account = result[kSecAttrAccount as String] as? String else { throw KeychainError.unexpectedItemData }
let passwordItem = KeychainPasswordItem(service: service, account: account, accessGroup: accessGroup)
passwordItems.append(passwordItem)
}
return passwordItems
}
// MARK: Convenience
private static func keychainQuery(withService service: String, account: String? = nil, accessGroup: String? = nil) -> [String : AnyObject] {
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrService as String] = service as AnyObject?
if let account = account {
query[kSecAttrAccount as String] = account as AnyObject?
}
if let accessGroup = accessGroup {
query[kSecAttrAccessGroup as String] = accessGroup as AnyObject?
}
return query
}
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="qhh-TY-2DC"/>
<viewControllerLayoutGuide type="bottom" id="Oj5-df-MCz"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="m_loading.jpg" translatesAutoresizingMaskIntoConstraints="NO" id="LXY-iL-70L">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="LXY-iL-70L" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="MZ2-ry-so8"/>
<constraint firstAttribute="trailing" secondItem="LXY-iL-70L" secondAttribute="trailing" id="XU5-3v-LZR"/>
<constraint firstItem="LXY-iL-70L" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="lhr-mm-KUV"/>
<constraint firstAttribute="bottom" secondItem="LXY-iL-70L" secondAttribute="bottom" id="yXs-ym-TTY"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="52.173913043478265" y="375"/>
</scene>
</scenes>
<resources>
<image name="m_loading.jpg" width="640" height="1280"/>
</resources>
</document>

View File

@ -0,0 +1,7 @@
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
- (instancetype)initWithEAGLView:(UIView*)eaglView;
@end

View File

@ -0,0 +1,24 @@
#import "ViewController.h"
@implementation ViewController
- (instancetype)initWithEAGLView:(UIView*)eaglView {
if (self = [super init]) {
self.view = eaglView;
}
return self;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskLandscape;
}
@end

View File

@ -0,0 +1,27 @@
//
// ViewController.swift
//
//
// Created by zhl on 2021/7/21.
// Copyright © 2021 egret. All rights reserved.
//
import UIKit
import Foundation
class ViewController: UIViewController {
convenience init(eaglView: UIView) {
self.init();
self.view = eaglView;
}
override var prefersStatusBarHidden: Bool {
return true;
}
//
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
//
override var shouldAutorotate: Bool {
return false
}
}

View File

@ -0,0 +1,111 @@
//
// AppDelegate.swift
//
//
// Created by zhl on 2020/6/17.
// Copyright © 2020 egret. All rights reserved.
//
import UIKit
import Foundation
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var _viewController: UIViewController?
var _imageView: UIImageView?
var _native: EgretNativeIOS = EgretNativeIOS.init()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let gameUrl = "http://local/game/index.html"
_native = EgretNativeIOS.init();
_native.config.showFPS = false;
_native.config.fpsLogTime = 30;
_native.config.disableNativeRender = false;
_native.config.clearCache = false;
_native.config.useCutout = true;
UIApplication.shared.isIdleTimerDisabled = true;
_viewController = ViewController.init(eaglView: _native.createEAGLView());
if (!(_native.initWith(_viewController))) {
return false;
}
self.setExternalInterfaces()
let networkState:String? = _native.getNetworkState();
if (networkState == "NotReachable") {
let native = _native;
_native.setNetworkStatusChangeCallback({ (state) in
if (state != "NotReachable") {
DispatchQueue.main.async {
native.startGame(gameUrl)
self.showLoadingView();
}
}
})
return true;
}
_native.startGame(gameUrl);
self.showLoadingView();
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// 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 invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// 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.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// 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.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func setExternalInterfaces() {
let support = _native;
_native.setExternalInterface("sendToNative", callback: { (message) -> () in
var str: String = "";
str.append(message!);
support.callExternalInterface("sendToJS", value: str);
})
_native.setExternalInterface("@onState", callback: { (message) -> () in
print("Get @onStage: %s", message as Any)
})
_native.setExternalInterface("@onError", callback: { (message) -> () in
print("Get @onError: %s", message as Any)
})
_native.setExternalInterface("getUid", callback: { (message) -> () in
print("Get @getUid: %s", message as Any)
let id = IDUtil.getUid();
support.callExternalInterface("sendUidToJS", value: id);
})
_native.setExternalInterface("removeNativeLoading", callback: { (message) -> () in
print("Get @removeNativeLoading: %s", message as Any)
self.hideLoadingView();
})
}
func showLoadingView() {
let image = UIImage(named: "m_loading.jpg");
_imageView = UIImageView(image: image);
_imageView?.contentMode = UIView.ContentMode.scaleAspectFill
_imageView?.frame = _viewController!.view.frame;
_viewController!.view.addSubview(_imageView!);
_viewController!.view.bringSubviewToFront(_imageView!);
}
func hideLoadingView(){
_imageView?.removeFromSuperview();
}
}

View File

@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,47 @@
//
// IDUtil.swift
//
//
// Created by zhl on 2020/6/17.
// Copyright © 2020 egret. All rights reserved.
//
import UIKit
public class IDUtil: NSObject{
static let serviceName = "Wjtx"
static let accessGroup: String? = nil
static let accountName = "wjtx_uid"
public static func getUid() -> String {
let id = getSavedUid()
if (id != "") {
return id
}
let strIDFV = UIDevice.current.identifierForVendor!.uuidString.lowercased();
saveUid(uid: strIDFV)
return strIDFV;
}
static func saveUid(uid: String) {
do {
let passwordItem = KeychainPasswordItem(service: serviceName, account: accountName, accessGroup: accessGroup)
try passwordItem.savePassword(uid)
} catch {
print("Error updating keychain - \(error)")
}
}
static func getSavedUid() -> String {
do {
let passwordItem = KeychainPasswordItem(service: serviceName, account: accountName, accessGroup: accessGroup)
let password = try passwordItem.readPassword()
return password
} catch {
print("Error reading password from keychain - \(error)")
return ""
}
}
}

View File

@ -0,0 +1,52 @@
<?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>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>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSPhotoLibraryAddUsageDescription</key>
<string></string>
<key>NSPhotoLibraryUsageDescription</key>
<string></string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,179 @@
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this samples licensing information
Abstract:
A struct for accessing generic password keychain items.
*/
import Foundation
struct KeychainPasswordItem {
// MARK: Types
enum KeychainError: Error {
case noPassword
case unexpectedPasswordData
case unexpectedItemData
case unhandledError(status: OSStatus)
}
// MARK: Properties
let service: String
private(set) var account: String
let accessGroup: String?
// MARK: Intialization
init(service: String, account: String, accessGroup: String? = nil) {
self.service = service
self.account = account
self.accessGroup = accessGroup
}
// MARK: Keychain access
func readPassword() throws -> String {
/*
Build a query to find the item that matches the service, account and
access group.
*/
var query = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
query[kSecMatchLimit as String] = kSecMatchLimitOne
query[kSecReturnAttributes as String] = kCFBooleanTrue
query[kSecReturnData as String] = kCFBooleanTrue
// Try to fetch the existing keychain item that matches the query.
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
// Check the return status and throw an error if appropriate.
guard status != errSecItemNotFound else { throw KeychainError.noPassword }
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
// Parse the password string from the query result.
guard let existingItem = queryResult as? [String : AnyObject],
let passwordData = existingItem[kSecValueData as String] as? Data,
let password = String(data: passwordData, encoding: String.Encoding.utf8)
else {
throw KeychainError.unexpectedPasswordData
}
return password
}
func savePassword(_ password: String) throws {
// Encode the password into an Data object.
let encodedPassword = password.data(using: String.Encoding.utf8)!
do {
// Check for an existing item in the keychain.
try _ = readPassword()
// Update the existing item with the new password.
var attributesToUpdate = [String : AnyObject]()
attributesToUpdate[kSecValueData as String] = encodedPassword as AnyObject?
let query = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
let status = SecItemUpdate(query as CFDictionary, attributesToUpdate as CFDictionary)
// Throw an error if an unexpected status was returned.
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
}
catch KeychainError.noPassword {
/*
No password was found in the keychain. Create a dictionary to save
as a new keychain item.
*/
var newItem = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
newItem[kSecValueData as String] = encodedPassword as AnyObject?
// Add a the new item to the keychain.
let status = SecItemAdd(newItem as CFDictionary, nil)
// Throw an error if an unexpected status was returned.
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
}
}
mutating func renameAccount(_ newAccountName: String) throws {
// Try to update an existing item with the new account name.
var attributesToUpdate = [String : AnyObject]()
attributesToUpdate[kSecAttrAccount as String] = newAccountName as AnyObject?
let query = KeychainPasswordItem.keychainQuery(withService: service, account: self.account, accessGroup: accessGroup)
let status = SecItemUpdate(query as CFDictionary, attributesToUpdate as CFDictionary)
// Throw an error if an unexpected status was returned.
guard status == noErr || status == errSecItemNotFound else { throw KeychainError.unhandledError(status: status) }
self.account = newAccountName
}
func deleteItem() throws {
// Delete the existing item from the keychain.
let query = KeychainPasswordItem.keychainQuery(withService: service, account: account, accessGroup: accessGroup)
let status = SecItemDelete(query as CFDictionary)
// Throw an error if an unexpected status was returned.
guard status == noErr || status == errSecItemNotFound else { throw KeychainError.unhandledError(status: status) }
}
static func passwordItems(forService service: String, accessGroup: String? = nil) throws -> [KeychainPasswordItem] {
// Build a query for all items that match the service and access group.
var query = KeychainPasswordItem.keychainQuery(withService: service, accessGroup: accessGroup)
query[kSecMatchLimit as String] = kSecMatchLimitAll
query[kSecReturnAttributes as String] = kCFBooleanTrue
query[kSecReturnData as String] = kCFBooleanFalse
// Fetch matching items from the keychain.
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
// If no items were found, return an empty array.
guard status != errSecItemNotFound else { return [] }
// Throw an error if an unexpected status was returned.
guard status == noErr else { throw KeychainError.unhandledError(status: status) }
// Cast the query result to an array of dictionaries.
guard let resultData = queryResult as? [[String : AnyObject]] else { throw KeychainError.unexpectedItemData }
// Create a `KeychainPasswordItem` for each dictionary in the query result.
var passwordItems = [KeychainPasswordItem]()
for result in resultData {
guard let account = result[kSecAttrAccount as String] as? String else { throw KeychainError.unexpectedItemData }
let passwordItem = KeychainPasswordItem(service: service, account: account, accessGroup: accessGroup)
passwordItems.append(passwordItem)
}
return passwordItems
}
// MARK: Convenience
private static func keychainQuery(withService service: String, account: String? = nil, accessGroup: String? = nil) -> [String : AnyObject] {
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrService as String] = service as AnyObject?
if let account = account {
query[kSecAttrAccount as String] = account as AnyObject?
}
if let accessGroup = accessGroup {
query[kSecAttrAccessGroup as String] = accessGroup as AnyObject?
}
return query
}
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="qhh-TY-2DC"/>
<viewControllerLayoutGuide type="bottom" id="Oj5-df-MCz"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="52.173913043478265" y="375"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,7 @@
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
- (instancetype)initWithEAGLView:(UIView*)eaglView;
@end

View File

@ -0,0 +1,24 @@
#import "ViewController.h"
@implementation ViewController
- (instancetype)initWithEAGLView:(UIView*)eaglView {
if (self = [super init]) {
self.view = eaglView;
}
return self;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskLandscape;
}
@end

View File

@ -0,0 +1,28 @@
//
// ViewController.swift
//
//
// Created by zhl on 2020/6/17.
// Copyright © 2020 egret. All rights reserved.
//
import UIKit
import Foundation
class ViewController: UIViewController {
convenience init(eaglView: UIView) {
self.init();
self.view = eaglView;
}
override var prefersStatusBarHidden: Bool {
return true;
}
//
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
//
override var shouldAutorotate: Bool {
return false
}
}

View File

@ -0,0 +1,6 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import <EgretNativeIOS.h>

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
ios-template/m_loading.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

13
ios-template/main.m Normal file
View File

@ -0,0 +1,13 @@
//
// main.m
// Copyright © 2018-2020 egret. 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]));
}
}

View File

@ -0,0 +1,7 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import <EgretNativeIOS.h>

View File

@ -0,0 +1,10 @@
<?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>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.ztgame.wjtxh5</string>
</array>
</dict>
</plist>

10
武极天下.entitlements Normal file
View File

@ -0,0 +1,10 @@
<?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>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.jc.wjtx</string>
</array>
</dict>
</plist>