vue-cli构建_构建自己的WotsApp-第7部分

vue-cli构建

I should start this article with a disclaimer: It is based on iOS 13, Swift 5, and Xcode 11.x. If you’re reading this and those numbers look dated, be forewarned.

我应该以免责声明开头:它基于iOS 13,Swift 5和Xcode11.x。 如果您正在阅读本文,并且那些数字看起来过时,请提前警告。

I should also warn you that notifications — principally remote ones — involve Apple’s infrastructure, which means you’ll need an Apple Developer account to use them. Of course, you also need one to use CloudKit.

我还应该警告您,通知(主要是远程通知)涉及Apple的基础设施,这意味着您需要有Apple Developer帐户才能使用它们。 当然,您还需要使用CloudKit。

Finishing off our review… of the review, I think we can sort out the last few of our issues with some design changes that will solve almost all of them in a single strike.

完成我们的审查…审查,我认为我们可以通过一些设计更改来解决最后几个问题,这些更改可以一次解决几乎所有问题。

In the last chapter, we did 3/4 of the work to block and hide entries. I came up with a plan to reverse the block. I’m not going to do that right now, though. Let’s first fix the multiple-user issue, which is more important.

在上一章中,我们做了3/4的工作来阻止和隐藏条目。 我想出了一个逆转计划。 不过,我现在不打算这样做。 让我们首先解决更重要的多用户问题。

第十三章 (Chapter 13)

Now I’m sure we’ll have two users who want the same login name. This we can all agree on. And there is a possibility with the current design that they’ll choose the same secret as well. The odds are far greater than you might imagine — just google common passwords. That combination would floor our current design.

现在,我确定我们会有两个想要相同登录名的用户。 我们都可以同意这一点。 当前的设计有可能他们也会选择相同的秘密。 可能性比您想象的要大得多-仅是Google通用密码。 这种结合将成为我们当前设计的基础。

We can solve this by creating the secret in-app, only we’ll call it a PIN code. People are used to being issued PINs — not secrets.

我们可以通过创建秘密的应用内程序来解决此问题,只有我们将其称为PIN码。 人们习惯于获得PIN,而不是秘密。

We can then use this to solve the same-name problem by making a subtle change to our protocol. When you click on a user, it won’t send a request to talk to the other party. It will ask you to confirm their PIN. We can store this PIN code in the public directory that we have scrambled with an MD5 hash. Yes, I know MD5 hashes are not very secure, but we’ve already got the code in the cryptographic package we installed… and we’re not building a bank, after all.

然后,我们可以通过对我们的协议进行细微更改来使用它来解决同名问题。 当您单击用户时,它不会发送与对方通话的请求。 它将要求您确认其PIN码。 我们可以将此PIN码存储在我们用MD5哈希值加扰的公共目录中。 是的,我知道MD5哈希不是很安全,但是我们已经在安装的加密软件包中包含了代码……毕竟,我们并没有建立银行。

When they click on a name, we’ll build a subset of all the users with that name and ask them to input the PIN. We can then use their name and the MD5 hash of the PIN they just entered to find the user they want to talk to in the subset we just downloaded.

当他们单击一个名称时,我们将使用该名称构建所有用户的子集,并要求他们输入PIN。 然后,我们可以使用他们的姓名和他们刚刚输入的PIN的MD5哈希值,在刚刚下载的子集中找到要与之交谈的用户。

Given that you already knew the code, we’ll assume it’s OK to connect, which considerably simplifies the whole dance.

鉴于您已经知道代码,我们将假定可以连接,这将大大简化整个舞蹈过程。

This way, we can have an unlimited number of duplicate names in our database with only a single one appearing when you list the directory. That is our first point addressed.

这样,我们在数据库中可以有无限数量的重复名称,当您列出目录时,只会出现一个。 这是我们要解决的第一点。

Now if I don’t need a box to type in a secret, I get that space back. So let’s use it for a group name.

现在,如果我不需要输入密码的框,我将获得该空间。 因此,让我们将其用作组名。

It’s a win-win. We’re not asking the user to enter more and we’re keeping the interface virtually untouched. In fact, the group name could be optional. It could even be an app purchase. Now there’s an idea. That’s our second point.

这是双赢。 我们不要求用户输入更多内容,而实际上保持界面不变。 实际上,组名可以是可选的。 甚至可能是购买应用程序。 现在有一个主意。 这是我们的第二点。

And let’s have a rule that says if you type in a group, it assumes you want to create a private directory and don’t want your name in the global one. Obviously, you need to share the group name with your friends. Otherwise, they’ll never find you. That is our third point.

让我们有一条规则说,如果您输入一个组,则假定您要创建一个私有目录,并且不想在全局目录中使用您的名字。 显然,您需要与朋友共享群组名称。 否则,他们将永远找不到你。 这是我们的第三点。

问题与解决方案 (The problem and the solution)

Edit the Crypto.swift file and add this short method to generate a PIN code:

编辑Crypto.swift文件并添加此简短方法以生成PIN码:

Yes, there is a remote possibility that you’ll get two users with the same name and the same code. But it doesn’t matter because we’ll be comparing the MD5 hashes of this code, which should be unique. Speaking of hashes, here is the code for the md5hash method that you need to add to the Crypto.swift file:

是的,您极有可能会获得两个具有相同名称和相同代码的用户。 但这没关系,因为我们将比较此代码的MD5哈希值,该值应该是唯一的。 说到哈希,这是您需要添加到Crypto.swift文件中的md5hash方法的代码:

Note that you’ll need to import the Cryptor library at the top of the file. Now move over to Storage.swift and edit the saveToPublic method. Add a call to the new md5hash method to it:

请注意,您需要在文件顶部导入Cryptor库。 现在移至Storage.swift并编辑saveToPublic方法。 md5hash添加对新md5hash方法的调用:

So when you add a user, their code will be automatically generated and saved raw in their private file and as a hash in their public file. It’s true to say that the public file isn’t really public — only this app can access it — but the principle is there. You don’t store private data in a public database. Finally, edit the ContentView.swift file and update the button to include the new method. This will get us going:

因此,当您添加用户时,他们的代码将自动生成并原始存储在其私有文件中,并作为哈希存储在其公共文件中。 可以说公共文件不是真正的公共文件,只有这个应用程序可以访问它,但是原理就在那里。 您不会将私有数据存储在公共数据库中。 最后,编辑ContentView.swift文件并更新按钮以包括新方法。 这将使我们前进:

OK, you should be ready to test. Make the changes, use the CloudKit dashboard to clear out your database, and try out the code. Create a new user and look to make sure you get a PIN code and indeed an MD5 hash on file.

好的,您应该已经准备好进行测试。 进行更改,使用CloudKit仪表板清除数据库,然后尝试代码。 创建一个新用户,并确保确保获得PIN码,并且文件上确实包含MD5哈希。

We need to make our changes to the protocol now — quite drastic changes, really. We’ll no longer be asking for permission to connect. We’re assuming if they know the code, they can connect. Let’s start with Storage.swift.

我们现在需要对协议进行更改-确实是相当大的更改。 我们将不再寻求连接许可。 我们假设他们知道代码,便可以连接。 让我们从Storage.swift开始。

I want a simple representation of a record, so I defined a new structure in Storage.swift and a new PassThroughPublisher to use it:

我想要一个记录的简单表示形式,因此我在Storage.swift定义了一个新结构,并使用了一个新的PassThroughPublisher来使用它:

With that done, I create a few new methods to use the new structure. We also need a method to return all the names, a second method to match the one you selected with the picker, and a third to update the authorization message of the one you confirmed, assuming the correct PIN code was given:

完成之后,我创建了一些新方法来使用新结构。 我们还需要一种方法来返回所有名称,第二种方法是将您选择的名称与选择器进行匹配,第三种方法是更新您确认的名称的授权消息,假设给出了正确的PIN码:

And two methods to save the record when you confirm the code:

确认代码后,有两种保存记录的方法:

And this one. Note that we were saving the auth field to the private database, but with the changes to the protocol, we now need to save it to the public one:

还有这个。 请注意,我们将auth字段保存到私有数据库,但是随着协议的更改,我们现在需要将其保存到公共数据库:

One more change is needed to the contentView.swift to make full use of our new protocol. Under the pickerView, you need to change/add this tag. Note that we used a much more SwiftUI-ish popover here:

要充分利用我们的新协议,需要对contentView.swift进行另一处更改。 在pickerView ,您需要更改/添加此标签。 请注意,我们在这里使用了更多的类似于SwiftUI的弹出式窗口:

Finally, we need to make a small change to the directory lister again:

最后,我们需要再次对目录列表器进行一些更改:

Together with the initial one that we call:

与我们称为的最初一个一起:

And you’re ready for another test. Add a second user to one of your devices with the same name and go for it.

您已经准备好进行另一项测试。 将第二个用户添加到您的一个具有相同名称的设备并继续使用。

It feels like a cleaner solution, but wait: There are two major drawbacks to it.

感觉像是一种更清洁的解决方案,但请等待:它有两个主要缺点。

  • Once you’ve authorised a user on a device, all the users on that device are authorised.

    对设备上的用户进行授权后,该设备上的所有用户都将得到授权。
  • Even worse, once you’ve authorised one person, you’ve authorised everybody because we saved the auth in the public directory.

    更糟糕的是,一旦您授权了一个人,您就授权了所有人,因为我们将auth保存在公共目录中。

We either need to change the public database so that authorised users is a list of individual accounts under the auth field or we save it on the device. The former sounds good and will mean we won’t lose authorised users if we change our device, but if we change our device, we change our notification signature. Let’s re-jig this to save it locally.

我们要么需要更改公共数据库,以便authorised usersauth字段下的单个帐户列表,要么将其保存在设备上。 前者听起来不错,这意味着如果我们更改设备,我们不会失去授权用户,但是如果我们更改设备,我们将更改通知签名。 让我们重新调整它以将其保存在本地。

These two routines will save and/or confirm our token to the shared memory:

这两个例程会将我们的令牌保存和/或确认到共享内存:

And we just need to change the ContentView.swift check and use the saving routines. I commented out the call to save to the public database and added the new one in here:

我们只需要更改ContentView.swift检查并使用保存例程即可。 我注释了保存到公共数据库的调用,并在此处添加了新的调用:

Time to test again, although you’re going to need three real devices this time so that you create three users, authenticate one to talk to the second, and check that the third still needs to authenticate.

需要再次测试,尽管这次您将需要三个真实的设备,以便您创建三个用户,对一个用户进行身份验证以与第二个用户进行对话,并检查第三个用户是否仍需要进行身份验证。

What’s left?

还剩下什么?

  • Unblocking of accounts (you recall part 4/4).

    解锁帐户(您会回想第4/4部分)。
  • Implement groups.

    实施小组。
  • Implement more security (so that you don’t have an unlimited number of tries to set up notifications between parties).

    实施更高的安全性(这样,您就可以无限制地尝试在各方之间建立通知)。
  • Sort out the badges that appear on the icon so that they make more sense.

    整理出现在图标上的徽章,使它们更有意义。
  • Clean up the code, get rid of mothballed methods.

    清理代码,摆脱封存的方法。

第十四章 (Chapter 14)

I want to use a shake gesture to invoke a restore method for the blocked accounts. Just before I start, I should mention that this has been a challenge to implement because blocked devices are blocked in three places: on the local device in memory, on the remote device in memory, and on the remote device in other users’ private databases.

我想使用摇动手势为被阻止的帐户调用restore方法。 在开始之前,我要提一下实现这是一个挑战,因为被阻止的设备在三个位置被阻止:内存中的本地设备,内存中的远程设备以及其他用户的私有数据库中的远程设备。

This routine picks up the shake action. You need to add it to the end of your ContentView.swift file. That was the easy bit:

此例程拾取震动动作。 您需要将其添加到ContentView.swift文件的末尾。 这很容易:

Still working within the ContentView.swift, this code brings up a new branch when triggered by the togglePublisher. This will list the blocked accounts:

仍然在ContentView.swift工作,当由togglePublisher触发时,此代码会弹出一个新分支。 这将列出被阻止的帐户:

The togglePublisher itself is triggered here. I commented out a few methods we have yet to implement.

togglePublisher本身在此处触发。 我评论了一些我们尚未实现的方法。

Text("WotsApp")
.onReceive(togglePublisher) { (_) in
self.display4 = !self.display4
self.display5 = !self.display5
}

Add these methods to your project, compile, and run. Depending on your setup, it may or may not work. There is a subtle bug here. The blocked account data is held in the private database of the person who is blocked. If you’ve been running this on devices all logged into the same Apple ID, it’ll work. But if you’ve been running this on devices logged into separate accounts — as they should be — it won’t work because the blocked tag is held in the private database of the individual who is blocked.

将这些方法添加到项目中,进行编译和运行。 根据您的设置,它可能会或可能不会起作用。 这里有一个细微的错误。 被阻止的帐户数据保存在被阻止者的私人数据库中。 如果您一直在所有登录了相同Apple ID的设备上运行此程序,那么它将起作用。 但是,如果您一直在登录到单独帐户的设备上运行此操作(应该如此),则该操作将无法正常工作,因为被blocked标记保存在被阻止者的私有数据库中。

Sure, you don’t recall, but we needed to do it that way because we need to stop the message from being sent at the source.

当然,您不会想起,但是我们需要那样做,因为我们需要阻止消息从源头发送。

There is another issue too. If party A blocks party B, we’re good… but only until part B reinstalls the app and gets a new token value.

还有一个问题。 如果甲方阻止了乙方,那么我们很好……但是直到乙方重新安装应用程序并获得新的令牌值。

One step at a time, though. We’re looking at the unblock solution. To make this work, both users need to be online and running the app at the same time. Let’s continue.

一次只一步。 我们正在寻找畅通无阻的解决方案。 为了使这项工作有效,两个用户都必须在线并同时运行该应用程序。 让我们继续。

Edit RemoteNotifications.swift and add an unblockMessage method. This is going to be one of those background notifications we talked about in an earlier chapter:

编辑RemoteNotifications.swift并添加unblockMessage方法。 这将是我们在上一章中讨论的那些背景通知之一:

Now edit your appDelegate and make this change. Here, we’re clearing the local memory and the private database:

现在,编辑您的appDelegate并进行更改。 在这里,我们正在清除本地内存和私有数据库:

if request == "unblock" {
cloud.searchNReturn(device!, action: "unblock")
cloud.saveUnblockedTokenToSharedmemory(token2U: device!)
}

Now you’ll need to edit the method in Storage.swift and add a new action:

现在,您需要在Storage.swift编辑该方法并添加一个新操作:

And add this method (the one triggered by the new action) to the same file:

并将此方法(由新操作触发的方法)添加到同一文件:

And of course, you’ll need the method to save the unblocked token back to memory:

当然,您将需要将未阻塞的令牌保存回内存的方法:

You should be ready for another test. Clear down your database using the CloudKit dashboard and add some new accounts to two different devices. Now send yourself notifications from one to the other. If you’re confident that everything still works, try blocking messages from one to the other. Check that they are blocked. Relaunch everything and give one of the devices a shake. Unblock the account and then try sending a message again. You may have to search for the name since it wouldn’t have been displayed when you restarted.

您应该准备进行另一项测试。 使用CloudKit仪表板清除数据库并将新帐户添加到两个不同的设备。 现在,将自己的通知从一个发送给另一个。 如果您确信一切仍然正常,请尝试阻止从一个到另一个的消息。 检查它们是否被阻塞。 重新启动所有设备,并摇晃其中一台设备。 取消阻止该帐户,然后尝试再次发送消息。 您可能需要搜索名称,因为重新启动时不会显示该名称。

There’s another bug linked to multiple users too: If you block a user, it blocks everybody on that device.

还有一个错误也链接到多个用户:如果您阻止一个用户,它将阻止该设备上的每个人。

结论 (Conclusion)

We need to take another break for some air. What seemed like a simple app has turned into a monster piece of engineering with snags appearing almost as quickly as we fix them. I must confess that I’m worried that I missed something on our journey and left you high and dry. Let me know if that is the case and I’ll try and rescue you.

我们需要再休息一下。 看起来像一个简单的应用程序已经变成了一个庞大的工程,几乎可以像我们修复它们一样快地出现障碍。 我必须承认,我担心自己在旅途中错过了一些东西,使您身高不胜。 让我知道是否是这种情况,我会尽力营救您。

In chapter 10, I said we had reached the end, but I subsequently decided that I had dropped too many balls. We have addressed almost all of them and I think I really need to close this series now. Thank you for coming with me on this exploration. I hope you enjoyed reading this series as much as I enjoyed writing it and indeed learned some new things along the way.

在第10章中,我说我们已经走到了尽头,但随后我决定我丢了太多球。 我们已经解决了几乎所有问题,我认为我现在确实需要结束本系列。 感谢您与我一起进行这项探索。 我希望您喜欢阅读本系列文章的过程和阅读本系列文章的过程一样,并确实学习了一些新东西。

翻译自: https://medium.com/better-programming/building-your-own-wotsapp-part-7-47b9b66b3db4

vue-cli构建

你可能感兴趣的:(python,java)