破解 WD MyCloud Gen2 安装第三方应用

本篇教程基于的环境

  1. 机器是 WD MyCloud Gen2,固件版本是 2.21.126;
  2. WD MyCloud 开启 SSH 访问的功能;
  3. 开发环境是 macOS;

下载所需文件

去百度网盘下载所需文件。

链接: https://pan.baidu.com/s/1kVhuAgB 密码: 8wj6

破解步骤

  1. 登陆 WD MyCloud 的控制面板,在「设置」中开启「SSH」功能。
  2. 通过 SSH 登陆到 WD MyCloud。不知道如何登陆?参考这里
  3. 将下载完成后的 define.js 文件复制到 Public 的目录下。不知道如何在 Terminal 里复制文件?参考这里
  4. 在 Terminal 中运行以下命令行。rm /usr/local/model/web/pages/function/define.jsln -sf /mnt/HD/HD_a2/Public/define.js /usr/local/model/web/pages/function/define.js。这样就顺利破解 WD MyCloud,可以安装第三方的应用了。
  5. 首先需要安装的是 WDMyCloud_WDCrack_1.1.bin 这个东西,这是必须的。登陆 WD MyCloud 的控制面板,在应用中将此文件安装。
  6. 到这一步,你就安装其他所有的 App 了,按需安装即可。

参考


This is the end of post

Sereval Basic Linux Netstat Command

What is Netstat?

In computing, netstat (network statistics) is a command-line network utility tool that displays network connections for the Transmission Control Protocol (both incoming and outgoing), routing tables, and a number of network interface (network interface controller or software-defined network interface) and network protocol statistics.

List out all connections

The most simple command is to list out all the current connections by using:
netstat -a

Example:

1
2
3
4
5
6
7
8
9
$ netstat -a

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 enlightened:domain *:* LISTEN
tcp 0 0 localhost:ipp *:* LISTEN
tcp 0 0 enlightened.local:54750 li240-5.members.li:http ESTABLISHED
tcp 0 0 enlightened.local:49980 del01s07-in-f14.1:https ESTABLISHED
tcp6 0 0 ip6-localhost:ipp [::]:* LISTEN

Get process name/pid and user id

When viewing the open/listening ports and connections, its often useful to know the process name/pid which has opened that port or connection.
You can use the following command:
sudo netstat -nlpt

Example:

1
2
3
4
5
6
~$ sudo netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN 1144/dnsmasq
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 661/cupsd
tcp6 0 0 ::1:631 :::* LISTEN 661/cupsd

Reference


This is the end of post

WD MyCloud 安装 Aria2 教程

本篇教程基于的环境

  1. 机器是 WD MyCloud Gen2,固件版本是 2.21.126;
  2. 开发环境是基于 macOS 的基础;
  3. 需要使用 Terminal 来输入相关语句;
  4. 需要使用 Linux 语句进行相关操作;
  5. WD MyCloud 可以安装外部应用;
  6. WD MyCloud 开启 SSH 访问的功能;

WD MyCloud 相关操作

下载所需文件

从以下链接中下载整个文件夹,里面包含三个文件。

  1. WDMyCloud_aria2_1.29.0.bin(11212016) 是将 aria2 安装到 WD MyCloud 上的应用程序;
  2. aria2.confaria2 的配置文件;
  3. aria2c 是交叉编译文件,具体是做什么的,你把它理解成破译文件就行。

链接: https://pan.baidu.com/s/1jIHUkgY 密码: ex4d

安装 aria2 应用程序

登陆到 WD MyCloud,进入应用程序的安装界面,选择 WDMyCloud_aria2_1.29.0.bin(11212016) 后进行安装。

将其他两个文件复制到 config 文件夹

安装完 aria2 后,会自动生成相关的一系列文件夹。打开 Terminal 通过 ssh 登陆到 root,输入 cd ~ 进入最底层文件夹,然后输入 cd mnt/HD/HD_a2/Nas_Prog/aria2/config/ 进入 config 的文件夹。

通过 scp 的命令将 aria2.confaria2c 复制到 config 文件夹的目录里。

运行 aria2

在 Terminal 里输入如下命令即可运行。

1
2
3
4
aria2c --conf-path=/mnt/HD/HD_a2/Nas_Prog/aria2/config/aria2.conf -D
```

若想要 WD MyCloud 在后台持续运行,则需要输入以下命令。

nohup ./aria2c –conf-path=/mnt/HD/HD_a2/Nas_Prog/aria2/config/aria2.conf -D &

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

#### 进行 **aria2** 网页版的相关设置
登录 `http://192.168.1.11/aria2/web_yaaw/index.html` 就会显示 **aria2** 的下载列表。

选择右上角的扳手符号进行设置,将 `JSON-RPC Path` 设置成 `http://token:abcd@host:port/jsonrpc`,`abcd` 是你在 **aria2.conf** 中设置的 token,将 **host:port** 设置成你自己的地址。

设置成功后右上角会显示当前 **Aria2** 的版本,同时会有成功链接的提示。

以上就是 WD MyCloud 这一部分的全部操作,接下需要在百度网盘上进行设置。

### 百度网盘相关操作
#### 下载 aria2 的插件
在本案例下,我是使用 Google Chrome 的。

进入 Chrome Web Store,搜索 aria2 的插件,然后安装到浏览器上。

#### 设置百度网盘插件
进入百度网盘, aria2 的插件会初始化,成功后你会看到「导出下载」的选项,光标悬浮后选择「设置」按钮。如下图:
![add](/assets/img/in-post/2017-04-04/002.png)

在地址栏里输入正确的地址,本案例中应该是 `http://token:abcd@host:port/jsonrpc`,`abcd` 是你在 **aria2.conf** 中设置的 token,将 **host:port** 设置成你自己的地址。

#### 导出下载
选择你需要下载的资源,选中后有会「导出下载」的按钮,选择第一个「ARIA2 RPC」,这样就能将资源导入到 WD MyCloud 上下载了。

#### 确认下载
登录 `http://192.168.1.11/aria2/web_yaaw/index.html` 查看下载列表,如果按照以上步骤进行顺利进行的话,资源应该处于全速下载中了。

以上就是本教程的全部内容,接下来是我在安装过程中本人遇到的问题,如果你也遇到了同样的问题,可以参考如何解决的。

### FAQ 环节
#### 无法使用 ssh 登陆到 root?
如果你登陆到 root 的时候得到这样的反馈

Unable to negotiate with 192.168.1.11 port 22: no matching host key type found. Their offer: ssh-dss

1
2
3
4
5
6
7
8
9
10
你需要进行如下的操作。

第一种是简单方法:直接输入 `ssh -oHostKeyAlgorithms=+ssh-dss root@192.168.1.11`,这样就可以顺利输入密码后登录了。

第二种是一劳永逸的方法,也是值得推荐的。
1. 打开 Terminal,输入`cd ~/.ssh/`
2. 使用 `vi config` 新建一个 config 的文件,然后将下列代码直接复制进去。
3. 如果你不熟悉 Linux 的操作语言,输入 `vi config` 后输入 `i` 进行编辑,使用 `command + v` 可以将代码粘贴进去,按下 `esc` 后再输入 `:x` 就可以保存退出该文件了。

`config` 的配置文件:

Host my.host.com .myinsecure.net 192.168.1. 192.168.2.*
HostKeyAlgorithms ssh-dss
KexAlgorithms diffie-hellman-group1-sha1

1
2
3

#### 如何将文件从 macOS 复制到 Linux 上?
使用 `scp` 的语句即可实现 macOS 和 Linux 之间的文件互传。在本篇教程中,我们需要将 aria2 的两个文件复制粘贴到 MyCloud aria2 的根目录里,即`/mnt/HD/HD_a2/Nas_Prog/aria2/config/`。假设 aria2 在 macOS 桌面上,需要使用的语句如下:

scp -r /Users/weixia/Desktop/aria2c root@192.168.1.11:/mnt/HD/HD_a2/Nas_Prog/aria2/config/
scp -r /Users/weixia/Desktop/aria2.conf root@192.168.1.11:/mnt/HD/HD_a2/Nas_Prog/aria2/config/

1
2
3
4
输入后 Terminal 会提示要你输入密码,成功输入密码后,就可以顺利地将 aria2c 和 aria2.conf 两个文件之间复制到 `/mnt/HD/HD_a2/Nas_Prog/aria2/config/` 的目录里。

#### RPC 报错,无法捆绑 TCP 怎么办?
输入 `aria2c --conf-path=/mnt/HD/HD_a2/Nas_Prog/aria2/config/aria2.conf` 之后报错,得到以下的 error message。

04/04 21:51:30 [^[[1;31mERROR^[[0m] IPv4 RPC: failed to bind TCP port 6800
Exception: [SocketCore.cc:312] errorCode=1 Failed to bind a socket, cause: Address already in use

04/04 21:51:30 [^[[1;31mERROR^[[0m] IPv6 RPC: failed to bind TCP port 6800
Exception: [SocketCore.cc:312] errorCode=1 Failed to bind a socket, cause: ai_family not supported

04/04 21:51:30 [^[[1;31mERROR^[[0m] Exception caught
Exception: [DownloadEngineFactory.cc:219] errorCode=1 Failed to setup RPC server.

1
第一,需要在 aria2.conf 的配置里禁用 IPv6,添加如下代码即可:

禁用IPv6, 默认:false

disable-ipv6=true

1
第二,在 Terminal 里输入

aria2c –conf-path=/mnt/HD/HD_a2/Nas_Prog/aria2/config/aria2.conf -D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
即可让 Aria2 开始工作。

#### 无法成功登陆 Aria2,RPC 服务器报错
先查看你使用的 Aria2 是哪个版本?
1. v1.18.6以上:使用 `rpc-secret=abcd` 登陆的,此时登陆选项设置应该是 `http://token:abcd@host:port/jsonrpc`
2. v1.15.2 - v1.18.5:使用 `--rpc-user=user --rpc-passwd=pwd` 登陆的,此时的登陆选项设置应该是 `http://user:pwd@host:port/jsonrpc`

RPC 的设置在 **aria.conf** 的文件里,需要看清楚是什么。

登陆选项设置需要在两个地址设置:
1. 在下载器里设置,就是 YAAW 里将地址设置成对的地址;
2. 在百度网盘的导出下载里,也需要将地址设置成对的地址。

#### 查询端口使用情况
如果在报错里出现 `Address already in use`,不妨查查是哪个程序占用了这个端口。
在 Ternimal 里输入 `sudo netstat -nlpt` 即可查询端口使用情况,还能看到是哪个程序。

#### Public 文件夹无故消失了怎么办?
进入 WD MyCloud 的控制面板,找到「共享」一栏,然后添加共享文件夹,一般情况下是添加 Public 文件夹,根据你之前的设置而添加。如下图:
![add](/assets/img/in-post/2017-04-04/001.png)

### 参考
* [Mac Linux Terminal: SSH File Transfer](https://www.youtube.com/watch?v=EJOoiYtyPTE)
* [SSH returns: no matching host key type found. Their offer: ssh-dss](http://askubuntu.com/questions/836048/ssh-returns-no-matching-host-key-type-found-their-offer-ssh-dss)
* [10 basic examples of linux netstat command](http://www.binarytides.com/linux-netstat-command-examples/)
* [Aria2 & YAAW 使用说明](http://aria2c.com/usage.html)
* [aria2配置示例](https://binux.blog/2012/12/aria2-examples/)
* [使用Aria2下载百度网盘和115的资源](https://blog.icehoney.me/posts/2015-01-31-Aria2-download)
* [Aria2 & YAAW 使用说明](http://aria2c.com/usage.html)


### 下载
**aria2.conf** 配置文件(仅供参考)

‘#’开头为注释内容, 选项都有相应的注释说明, 根据需要修改

被注释的选项填写的是默认值, 建议在需要修改时再取消注释

文件保存相关

文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置

dir=/shares/Public/Aria2

启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M

#disk-cache=32M

文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc

预分配所需时间: none < falloc ? trunc < prealloc

falloc和trunc则需要文件系统和内核支持

NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项

file-allocation=none

断点续传

continue=true

下载连接相关

最大同时下载任务数, 运行时可修改, 默认:5

max-concurrent-downloads=5

同一服务器连接数, 添加时可指定, 默认:1

max-connection-per-server=1

最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M

假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载

min-split-size=10M

单个任务最大线程数, 添加时可指定, 默认:5

split=5

整体下载速度限制, 运行时可修改, 默认:0

#max-overall-download-limit=0

单个任务下载速度限制, 默认:0

#max-download-limit=0

整体上传速度限制, 运行时可修改, 默认:0

#max-overall-upload-limit=0

单个任务上传速度限制, 默认:0

#max-upload-limit=0

禁用IPv6, 默认:false

disable-ipv6=true

进度保存相关

从会话文件中读取下载任务

input-file=/etc/aria2/aria2.session

在Aria2退出时保存错误/未完成的下载任务到会话文件

save-session=/etc/aria2/aria2.session

定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0

#save-session-interval=60

RPC相关设置

启用RPC, 默认:false

enable-rpc=true

允许所有来源, 默认:false

rpc-allow-origin-all=true

允许非外部访问, 默认:false

rpc-listen-all=true

事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同

#event-poll=select

RPC监听端口, 端口被占用时可以修改, 默认:6800

#rpc-listen-port=6800

设置的RPC授权令牌, v1.18.4新增功能, 取代 –rpc-user 和 –rpc-passwd 选项

#rpc-secret=secret

BT/PT下载相关

当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true

#follow-torrent=true

BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999

listen-port=51413

单个种子最大连接数, 默认:55

#bt-max-peers=55

打开DHT功能, PT需要禁用, 默认:true

enable-dht=false

打开IPv6 DHT功能, PT需要禁用

#enable-dht6=false

DHT网络监听端口, 默认:6881-6999

#dht-listen-port=6881-6999

本地节点查找, PT需要禁用, 默认:false

#bt-enable-lpd=false

种子交换, PT需要禁用, 默认:true

enable-peer-exchange=false

每个种子限速, 对少种的PT很有用, 默认:50K

#bt-request-peer-speed-limit=50K

客户端伪装, PT需要

peer-id-prefix=-TR2770-
user-agent=Transmission/2.77

当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0

seed-ratio=0

强制保存会话, 话即使任务已经完成, 默认:false

较新的版本开启后会在任务完成后依然保留.aria2文件

#force-save=false

BT校验相关, 默认:true

#bt-hash-check-seed=true

继续之前的BT任务时, 无需再次校验, 默认:false

bt-seed-unverified=true

保存磁力链接元数据为种子文件(.torrent文件), 默认:false

bt-save-metadata=true
`


This is the end of post

How to simulate GPS location without jailbreaking on iPhone?

Prepare for simulating GPS

  1. Download this repository from Github.
  2. Get the coordinates of the place you want to go. In this example, I want to simulate Reykjavik Airport in Iceland, which is 64.131933, -21.948947. You can easily find it in Google Maps.

Change latitude and longitude settings

Find heaven.gpx file in repository folder, and find code <wpt lat="64.131933" lon="-21.948947">. Change whereever you want to go.

Install in your iPhone

Change the project settings in upper left corner. Find Produce --> Scheme --> Eidt Scheme --> Options, change Default Location to heaven, and choose device to your iPhone. Install it!

Check it out

Open Google Maps, and you will find GPS is already changed to the location you set. Have fun!

Reference


This is the end of post

How to implement highlight in Jekyll 3.0?

Why do we need change?

On February 2, 2016, Github posted an article about an update in Github Page. Basically, it will run Jekyll 3.0 in Github Page, and the major impact are below:

  1. GitHub Pages will only support kramdown, Jekyll’s default Markdown engine.
  2. GitHub Pages now only supports Rouge.
  3. Local builds are significantly faster.

If you are building your website under Github Page, or even use Jekyll 3.0 to build directly, the main problem is that the old highlight function is no long workable. This post is gonna talk about how to use Rouge highlight under Jekyll 3.0.

Configuration setting

First of all, change some settings in your _config.yml. markdown will use kramdown, highlighter will use rouge, also change syntax_highlighter to rouge. Below is the code:

1
2
3
4
5
highlighter: rouge
markdown: kramdown
kramdown:
input: GFM
syntax_highlighter: rouge

Use Rouge Highlight

Install rouge first locally, and change to whichever style you like.

Install Rouge

1
$ gem install rouge

Rouge style

1
2
3
4
5
6
7
8
9
10
11
12
$ rougify help style

usage: rougify style [<theme-name>] [<options>]

Print CSS styles for the given theme. Extra options are
passed to the theme. Theme defaults to thankful_eyes.

options:
--scope (default: .highlight) a css selector to scope by

available themes:
base16, base16.dark, base16.monokai, base16.monokai.light, base16.solarized, base16.solarized.dark, colorful, github, molokai, monokai, monokai.sublime, thankful_eyes

You can find many avaiable themes, choose whichever you like. I would like to use monokai.sublime as an example.

1
$ rougify style monokai.sublime > assets/css/syntax.css

It will generate a css file, link this css file into html, and highlight will be avaiable in your website.

1
<link href="/assets/css/syntax.css" rel="stylesheet">

Change Background Color

If you prefer to use black as your code block background color, you should add the following code into css file.

1
pre[class='highlight'] {background-color:#000000;}

Reference


This is the end of post

A Standard Placeholder for Lorem Ipsum

What is Lorem ipsum?

A common form of lorem ipsum reads below with words altered, added, and removed to make it nonsensical, improper Latin.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Reference


This is the end of post

How to mix UIKit and TVMLKit within one app?

Question

I’m exploring tvOS and I found that Apple offers nice set of templates written using TVML. I’d like to know if a tvOS app that utilises TVML templates can also use UIKit.

Can I mix UIKit and TVMLKit within one app?

Answer One

Yes, you can. Displaying TVML templates requires you to use an object that controls the JavaScript Context: TVApplicationController.

1
var appController: TVApplicationController?

This object has a UINavigationController property associated with it. So whenever you see fit, you can call:

1
2
let myViewController = UIViewController()
self.appController?.navigationController.pushViewController(myViewController, animated: true)

This allows you to push a Custom UIKit viewcontroller onto the navigation stack. If you want to go back to TVML Templates, just pop the viewController off of the navigation stack.

If what you would like to know is how to communicate between JavaScript and Swift, here is a method that creates a javascript function called pushMyView()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func createPushMyView(){

//allows us to access the javascript context
appController?.evaluateInJavaScriptContext({(evaluation: JSContext) -> Void in

//this is the block that will be called when javascript calls pushMyView()
let pushMyViewBlock : @convention(block) () -> Void = {
() -> Void in

//pushes a UIKit view controller onto the navigation stack
let myViewController = UIViewController()
self.appController?.navigationController.pushViewController(myViewController, animated: true)
}

//this creates a function in the javascript context called "pushMyView".
//calling pushMyView() in javascript will call the block we created above.
evaluation.setObject(unsafeBitCast(pushMyViewBlock, AnyObject.self), forKeyedSubscript: "pushMyView")
}, completion: {(Bool) -> Void in
//done running the script
})
}

Once you call createPushMyView() in Swift, you are free to call pushMyView() in your javascript code and it will push a view controller onto the stack.

Answer Two

If you already have a native UIKit app for tvOS, but would like to extend it by using TVMLKit for some part of it, You can.

Use the TVMLKit as a sub app in your native tvOS app. The following app shows how to do this, by retaining the TVApplicationController and present the navigationController from the TVApplicationController. The TVApplicationControllerContext is used to transfer data to the JavaScript app, as the url is transferred here :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ViewController: UIViewController, TVApplicationControllerDelegate {
// Retain the applicationController
var appController:TVApplicationController?
static let tvBaseURL = "http://localhost:9001/"
static let tvBootURL = "\(ViewController.tvBaseURL)/application.js"

@IBAction func buttonPressed(_ sender: UIButton) {
print("button")

// Use TVMLKit to handle interface

// Get the JS context and send it the url to use in the JS app
let hostedContContext = TVApplicationControllerContext()
if let url = URL(string: ViewController.tvBootURL) {
hostedContContext.javaScriptApplicationURL = url
}

// Save an instance to a new Sub application, the controller already knows what window we are running so pass nil
appController = TVApplicationController(context: hostedContContext, window: nil, delegate: self)

// Get the navigationController of the Sub App and present it
let navc = appController!.navigationController
present(navc, animated: true, completion: nil)
}

Reference


This is the end of post

How to solve CORS issue in XMLHttpRequest by using Node.js?

Question

I am trying to do API request by using RESTful API, however, I got error message below from console.

XMLHttpRequest cannot load http://example.com/abcd. Response to preflight request doesn’t pass access control check: The ‘Access-Control-Allow-Origin’ header has a value ‘http://example.com' that is not equal to the supplied origin. Origin ‘http://example.com' is therefore not allowed access.

Answer

Add the following code into app.js.

1
2
3
4
5
6
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
next();
})

Reference


This is the end of post

How to dismiss ViewController in Swift?

Question

I am trying to dismiss a ViewController in swift by calling dismissViewController in an IBAction.

1
2
3
4
5
6
7
8
9
@IBAction func cancel(sender: AnyObject) {
self.dismissViewControllerAnimated(false, completion: nil)
println("cancel")
}

@IBAction func done(sender: AnyObject) {
self.dismissViewControllerAnimated(false, completion: nil)
println("done")
}

I could see the println message in console output but ViewController never gets dismissed. What could be the problem?

Answer

Using Segue

If you present the viewController by pushing, you should use below to dismiss

1
navigationController.popViewControllerAnimated(true)

Using Modal

The dismiss is used to close ViewControllers that presented using modal

1
dismiss(animated: true, completion: nil)

Reference


This is the end of post

Set Initial Viewcontroller In Appdelegate

Question

I would like to set the initial viewcontroller from the appdelegate by using Swift.

Answer

Swift 2

1
2
3
4
5
6
7
8
9
10
11
12
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

let storyboard = UIStoryboard(name: "Main", bundle: nil)

let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginSignupVC")

self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()

return true
}

Swift 3

1
2
3
4
5
6
7
8
9
10
11
12
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)

let storyboard = UIStoryboard(name: "Main", bundle: nil)

let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginSignupVC")

self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()

return true
}

Reference


This is the end of post