Using an IDE other than Xcode for iOS development until recently was a rather lonely path. This however tends to change with recent developments in the Apple ecosystem. Swift runs officially on Linux, Windows, AWS lambda, docker, and other places where you wouldn’t expect to find a programming language made by Apple.
Apple also wants to enable Swift to be a first-class citizen in 3rd party IDEs providing error reporting and code auto-completion. For that reason, they are developing SourceKit-LSP with plugins ready for popular IDEs such as Visual Studio Code (aka VSCode).
苹果还希望让Swift成为第三方IDE中的一等公民,从而提供错误报告和代码自动完成功能。 出于这个原因,他们正在开发SourceKit-LSP ,其插件可用于流行的IDE,例如Visual Studio Code(又名VSCode)。
Why would you want to use an IDE other than Xcode? Well, Xcode is not available on Linux or Windows in the first place. But even when being on a Mac, VSCode offers several nice features among of them a killer one called Live Share that allows 2 or more developers to collaborate remotely on the same file with live code co-editing. You can think of it as Google Docs for code.
In the days of post-Covid and home office this feature is a real life saver and makes a developer’s life so much easier either if you want to do pair programming or briefly explain and get assistance on a certain task.
If you try to use Swift in VSCode you will get something like that:
如果您尝试在VSCode中使用Swift,则会得到类似以下内容:
The steps needed to enable VSCode for iOS development are basically 3:
启用VSCode进行iOS开发所需的步骤基本上是3:
Enable Swift language support启用Swift语言支持
Add iOS framework support添加iOS框架支持
Add “app” target support添加“应用”目标支持
Since this guide focuses on iOS and this is currently possible only with a Mac for the rest of the guide we will assume we are running on a Mac. Otherwise you can go as far a step 1.
Make sure you have Xcode and VSCode installed. This is the easiest way to hit the ground running since sourcekit-lsp comes prebundled with Xcode. Open a terminal and run:
Assuming that you don’t see any output this is normal and means it works as expected. Hit Ctrl+C to end the process.
假设您没有看到任何输出,这是正常现象,意味着它可以正常工作。 按Ctrl + C结束该过程。
构建SourceKit-LSP扩展 (Build the SourceKit-LSP extension)
Now it is time to build the SourceKit-LSP extension. There is an unofficial SourceKit-LSP — Unofficial CI build but this did not work for me. Building it from source is not that hard. Just make sure you have node.js installed and then run:
$ git clone https://github.com/apple/sourcekit-lsp.git$ cd sourcekit-lsp/Editors/vscode/
$ npm run createDevPackage
$ code --install-extension out/sourcekit-lsp-vscode-dev.vsix
After that restart VSCode.
之后,重新启动VSCode。
Contrary to what you might read elsewhere you don’t need to edit the source code of the extension at all.
与您在其他地方可能会读到的内容相反,您根本不需要编辑扩展程序的源代码。
If you try to open a Swift file now you will get an error
如果您现在尝试打开Swift文件,将会收到错误消息
配置扩展 (Configure the extension)
You need to let the plugin know the location of the sourcekit-lsp executable. Open settings.json from VSCode using Cmd+Shift+P and enter “Preferences: Open Settings (JSON)”.
What is we achieved so far is to enable Swift development but VSCode has no idea about iOS frameworks. If you try to import UIKit you will get an error.
Insert this JSON in settings.json. You might need to update the x86_64-apple-ios13.6-simulator line based on the current version that you have installed.
This will work for Swift packages that reference iOS frameworks like UIKit.
这将适用于引用iOS框架(如UIKit)的Swift软件包。
添加“应用”目标支持 (Add “app” target support)
So far we added iOS support but only for Swift packages. What if you want to work on a typical app target. Trying to open the root folder gives this error:
What if you want to work on an iOS app and not on a Swift Package? SourceKit-LSP always looks for a package.json in root folder assuming that it always deals with a Swift package. An iOS app is not a Swift package and for that reason we need to trick SourceKit-LSP by adding a dummy Package.swift. Add this file to the root of your project (same level as .xcodeproj)
? Sign in with Apple makes it easy for people to sign in to your apps and websites with the Apple ID they already have. Fully integrate Sign in with Apple into your app using secure requests, and by handling state changes and server notifications. We’ll also introduce new APIs that allow you to let existing users switch to Sign in with Apple quickly and easily.
Related : Introducing Sign In with Apple — WWDC19 (Introducing Sign In with Apple)
相关:与Apple一起介绍登录— WWDC19(与Apple一起介绍登录)
创建安全请求 ( Creating a secure request)
These nonce and state properties will allow you to verify that the authorization and credential you get after executing a request are the ones you were expecting.
这些nonce和state属性将使您能够验证执行请求后获得的授权和凭据是否与预期的一样。
确保您的请求 (Securing your request)
随机数 (Nonce)
The nonce is an opaque blob of data sent as a string in the request.
随机数是在请求中作为字符串发送的不透明数据块。
It is important to generate one unique nonce every time you create a new request as later on you will be able to verify this value.
每次创建新请求时都必须生成一个唯一的随机数,这一点很重要,稍后您便可以验证该值。
This will allow you to verify this value in your server, helping prevent replay attacks.
这将使您能够在服务器中验证此值,从而有助于防止重放攻击。
州 (State)
The state value is also an opaque blob of data sent with the request.
状态值也是随请求发送的不透明数据块。
Once key difference he has with the nonce value is that the state will be returned in the credential allowing you to locally match a credential to a request and verify this was generated from your application.
Example on how to get a credential from an authorization
有关如何从授权中获取凭证的示例
Inside of credential you will find properties containing the user information that you requested like name and email. You will also find important properties that will allow you to securely verify the request and create a session with your servers.
Cache the objects locally It is important to cache the objects you need in case of the failure communicating with your server due to poor connectivity.在本地缓存对象重要的是,在由于连接不良而无法与服务器通信的情况下,缓存所需的对象非常重要。
Verify the state value Make sure you verify the state value of the credential to be the same state value you previously generated.验证状态值确保验证证书的状态值与先前生成的状态值相同。
Validate the information with Apple The response contains an authorization code an identity token. Send these values to your server where they can be decoded. Once decoded, verify the received information as well as session with Apple servers.使用Apple验证信息响应包含授权码和身份令牌。 将这些值发送到可以对其进行解码的服务器。 解码后,验证接收到的信息以及与Apple服务器的会话。
How will the entry token will look when decoded by your server
当服务器解码时,入口令牌的外观如何
subject : A user identified that was returned to you on the authorization and will allow to create a session in your servers.
subject :根据授权返回给您的用户标识,将允许您在服务器中创建会话。
nonce : Verify these to be the same nonce you generated previously in the request. This will allow you to verify the authenticity of the authorization and help mitigate replay attacks.
You can exchange the authorization code with the Apple ID servers. And when this is successful you will receive a refreshed token and an access token for future calls as well as a new identity token that should be identical to the one you already have.
It is important that this method is called every time your application is launched or changes to the foreground. That way you will be able to react on time to any changes in status and present the appropriate scheme in your application to your user.
.authorized : You can fast track the user directly to your application and skip the login UI.
.authorized :您可以直接将用户快速跟踪到您的应用程序,并跳过登录UI。
.revoked : The user decided to sign out of your application. In this scenario you should sign the user out of your application. Close your session and present the login screen
.notFound : This will be returned when there was no credential matching the user identifier. Present a login screen so that the user can authenticate your application.
Ownership changed This will only be received by application that recently were transferred from one development team to another. (ex. after a company’s acquired)所有权已更改这只会由*近从一个开发团队转移到另一个开发团队的应用程序接收。 (例如,公司被收购后)
User migration needed User identifiers are unique to a team. So when transferring ownership of an application, the existing user will need to be migrated to a new user identifier to match the new team.需要用户迁移用户标识符对于团队是唯一的。 因此,在转让应用程序所有权时,需要将现有用户迁移到新的用户标识符以匹配新团队。
Silent migration This migration is handled silently. This is without any user interaction and can be triggered calling the same API used to create a new account or logging the user.静默迁移静默处理此迁移。 这没有任何用户交互,可以通过调用用于创建新帐户的相同API或记录用户来触发。
We can validate the transfer state of the user and generate the new user identifier that will match the new team.
我们可以验证用户的转移状态,并生成与新团队匹配的新用户标识符。
服务器通知 ( Server notifications)
?服务器到服务器开发人员通知 (? Server to server developer notifications)
Listening to these notifications will allow you to monitor things like credential state changes right from your server as well as receive other types of events.
侦听这些通知将使您可以直接从服务器监视诸如凭证状态更改之类的事情,并接收其他类型的事件。
Register You have to register your server endpoint on the Apple developer’s website.注册您必须在Apple开发人员的网站上注册服务器端点。
JWT Event Events will be sent as JSON web tokens signed by Apple.JWT事件事件将作为Apple签名的JSON网络令牌发送。
The email-disabled event which you can get if a user has decided to stop receiving emails on their email relay. The email enabled event means that the user opted back into receiving email messages.
It is important to note that this event as well as the email disabled will only be sent when the user previously decided to use a private email relay for their account.
重要的是要注意,仅当用户先前决定对其帐户使用私人电子邮件中继时,才会发送此事件以及禁用的电子邮件。
The consent-revoked event will be sent to you when a user decided to stop using their AppleID with your application and should be treated as a sign out by the user.
with使用Apple Button登录 ( Sign in with Apple Button)
?Swift UI支持 (? Swift UI support)
onRequest : This is the right place to add the requested scopes like name and email and the nonce state values.
onRequest :这里是添加请求的范围(如名称和电子邮件以及现时状态值)的正确位置。
onCompletion : We will get the result of the request and handle the success or failure cases just as you would on the delegate methods for the authorization controller.
?升级以使用Apple登录 ( ? Upgrading to Sign in with Apple)
What about users that are already using a traditional username and password based account and don’t want to fork their current account?
对于已经使用传统的基于用户名和密码的帐户并且不想分叉当前帐户的用户呢?
Secure It’s secure for both you and your users. Upgrading to Sign in with Apple is the easiest way to convert your accounts to two factor authentication.安全它对您和您的用户都是安全的。 升级到Apple登录是将帐户转换为两因素身份验证的*简单方法。
Reduce complexity Account recovery is also a lot less complicated with Sign in with Apple.降低复杂性使用Apple登录可以使帐户恢复变得简单得多。
Prevent duplicate accounts Utilizing this API will prevent the duplication of accounts.防止帐户重复使用此API将防止帐户重复。
→ Users that are already using a traditional username and password based account won’t abandon their current account, they can just upgrade.
→已经在使用传统的基于用户名和密码的帐户的用户不会放弃其当前帐户,而只需升级即可。
总览 (Overview)
One Tap Account Security Upgrades — WWDC20
一键式帐户安全性升级— WWDC20
三种升级流程 (Three flow for upgrades)
When security recommendations identifies a weak credential in the new password manager and settings.当安全建议确定新密码管理器和设置中的弱证书时。
When a user is interacting with your app utilizes password autofill and the selected credential is a weak credential.当用户与您的应用进行交互时,会使用密码自动填充功能,并且所选凭据是弱凭据。
When you invoke the new authentication services API via a user interaction that you specify within your app通过您在应用程序中指定的用户交互调用新的身份验证服务API时
convertAccountsToSignInWithAppleWithoutUserInteraction : Called initially by the extension hosting process in an attempt to upgrade the credential without user interaction.
viewDidLoad : This can be used to set up an intermediary user interface for the security step of flow if necessary. Providing intermediary UI to indicate progress might help provide the best user experience.
prepareInterfaceToConvertAccountToSignInWithApple : This is called just prior to your view appearing. It gets past the same ASPasswordCredential provided is a non user interaction flow.
ASAccountAuthenticationModificationViewController Used to control the flow of the upgrade.ASAccountAuthenticationModificationViewController用于控制升级流程。
Authorization It has function to request Sign in with Apple authorization.授权具有请求使用Apple授权登录的功能。
Request UI If you’re evaluating the credential or currently signed in account and determined that additional UI is needed to verify the account the extension context is used to request that the step up security UI is displayed.请求用户界面如果您正在评估凭据或当前已登录帐户,并且确定需要其他用户界面来验证该帐户,则扩展上下文用于请求显示安全性提升用户界面。
Complete This removes the existing credential.完成这将删除现有的凭证。
Cancel The extension context is also used in cases which you need to cancel the flow entirely.取消扩展上下文还用于需要完全取消流的情况。
getSignInWithAppleAuthorizationWithState : Displays the Sign in with Apple UI with your apps information asking the user to authorize the upgrade. Request in upgrade flows nonce and state is passed as a parameter to this call.
completeUpgradeToSignInWithApple : This lets the extension hosting process know that authorization completed successfully resulting in the removal of the password credential.
We begin the flow in the OS when toe user interacts with a weak credential and wants to upgrade that credential to Sign in with Apple.当用户与弱证书交互并想要升级该证书以使用Apple登录时,我们便开始在OS中进行操作。
Your account modification extension is initialized by the password managing process.您的帐户修改扩展名由密码管理过程初始化。
And the convert without UI function is called providing the password credential intended to be upgraded to Sign in with Apple.无需用户界面的转换功能称为提供旨在升级为使用Apple登录的密码凭证。
The extension’s job is to evaluate the past credential to make sure it is valid prior to upgrading to Sign n with Apple (At this point checking too see if the username matches the currently signed in user is a good first course of action.)扩展程序的工作是评估过去的凭据,以确保它在使用Apple升级到Sign n之前是有效的(此时,也请检查用户名是否与当前登录的用户匹配是否是很好的*步。)
The extension determined that the state of the signed in user and the pass credential requires a call to the server to verify the account.该扩展插件确定已登录用户的状态和传递凭据需要调用服务器以验证帐户。
The server verifies the credential and the authentication is a success.服务器验证凭据,并且身份验证成功。
The server then replies back to the extension confirming that the account is ready to be upgraded to Sign in with Apple.然后,服务器回复该扩展,以确认该帐户已准备好升级为使用Apple登录。
The account is confirmed as authenticated and eligible for upgrade the extension context would be used to request the Apple ID credential.该帐户被确认为已认证并且符合升级条件,扩展上下文将用于请求Apple ID凭据。
What would happen if there’s an issue with the account preventing an immediate upgrade?
如果帐户出现问题,无法立即升级,该怎么办
Flow begins when the user interacts with a weak credential and wants to upgrade that credential.当用户与弱凭证交互并想要升级该凭证时,流程开始。
Your account modification extension is then initialized by the password managing process.然后,您的帐户修改扩展名将由密码管理过程初始化。
Then the prepare to convert without UI function is called with the password credential.然后,使用密码凭证调用没有UI功能的准备转换。
The credential are then verified by the extension.然后,该凭证由扩展名验证。
The extension calls it verify credential function which results in a call today extensions back end to validate the credential.该扩展调用它的验证凭证功能,导致今天调用扩展后端来验证凭证。
The server will attempt to verify the account with the request.服务器将尝试使用请求验证帐户。
Sever determines that this account needs additional verification.服务器确定该帐户需要其他验证。
That reply comes back to the extension and the verified credential function evaluates this as a twoFactorAuthRequired.
该答复返回到扩展名,并且已验证的凭证函数将其评估为twoFactorAuthRequired 。
This case is handled by using the extension context to call cancel with error with the user interaction required error.通过使用扩展上下文来调用带错误的cancel并处理用户交互所需的错误,可以解决这种情况。
verifyCredential→ When the existing credential is verified one of these three values would get returned.
verifyCredential →验证现有凭据后,将返回这三个值之一。
.failure : Result for cases such as when the server attempts to validate the credential but the account or service date is not appropriate for converting the account at that time.
To avoid users having to do extra work in most cases where a user is already authenticated in your app.
为了避免用户在大多数情况下已经在您的应用中通过身份验证的用户做额外的工作。
使用UI转换 (Converting with UI)
There could be circumstances where UI flows might be warranted.
在某些情况下,可能需要确保UI流动。
After the extension contacts cancelled with the user interaction required error, the password managing process initializes a new instance of the account modification view controller在分机联系人因用户交互所需的错误而取消后,密码管理过程将初始化帐户修改视图控制器的新实例
And calls it prepared to convert with your function. Passing the ASPasswordCredential. (At this point, the extension’s ViewController is presented providing Intermediary UI such as a spinning gear.)并调用它准备好与您的函数进行转换。 传递ASPasswordCredential。 (此时,提供了扩展程序的ViewController,提供了中间UI(如旋转齿轮)。)
Utilizing the same credentials as earlier with perhaps a slight change of context a request is made to the back end.使用与先前相同的凭据,但可能会稍微改变上下文,从而向后端发出请求。
The server attempts to verify the account. Requires two F.A and sends a rely back to the extension.服务器尝试验证帐户。 需要两个FA,并将依赖项发送回扩展。
The extension updates the view asking the user for two factor authentication.该扩展程序更新了视图,要求用户进行两因素验证。
The user provides the verification code which the extension would then verify.用户提供扩展名随后将验证的验证码。
If the user could not be verified at this point, the extension context would be used to cancel the flow with the failed error.如果此时无法验证用户,则将使用扩展上下文来取消带有失败错误的流。
If the user provide a valid code and verification is a success, the extension is now ready to request the AppleID credential.如果用户提供了有效的代码并且验证成功,则该扩展现在可以请求AppleID凭据了。
升级帐号 (Upgrading account)
It is important to secure your request, to do so your extension would generate a state and nonce and pass them as parameters for the getAppleIDCredential call.保护您的请求很重要,这样做扩展将生成状态和随机数并将其作为参数传递给getAppleIDCredential调用。
This results in an upgrade to Sign in with Apple UI being displayed to the user.这导致向用户显示使用Apple UI登录的升级。
The user then authorizes using Face ID.然后,用户授权使用人脸ID。
The AppleIDCredential is provided to the extension in the completion block of the getAppleIDCredential call.AppleIDCredential在getAppleIDCredential调用的完成块中提供给扩展。
The extension would then verify the credentials stay properly as being the same generated earlier.然后,扩展名将验证凭据是否与之前生成的凭据保持一致。
The extension would them request an upgrade of the account providing the necessary account information and the AppleIDCredential to the server back end, so the account can be converted.该扩展将要求他们升级帐户,以向服务器后端提供必要的帐户信息和AppleIDCredential,以便可以转换帐户。
The back end would then exchange the authorization code with Apple servers verifying the value of the nonce in the identity token.然后,后端将与Apple服务器交换授权码,以验证身份令牌中随机数的值。
And if successful perform a conversion of the account.如果成功执行帐户转换。
After converting, it sends a reply back with a success value. It is important to note again that if the servers operation failed the extension contact should be used to call cancel with error with the failed error.转换后,它会发送带有成功值的回复。 再次重要的是要注意,如果服务器操作失败,则扩展联系人应用于调用带错误错误的带错误的取消。
This time the server is indicating success. So the extension will perform any required bookkeeping and then call a complete upgrade to Sign in with Apple on the extension context.这次服务器指示成功。 因此,扩展程序将执行所有必需的簿记工作,然后调用完整的升级以在扩展程序上下文中与Apple登录。
This result in the password manager removing the existing credential and with that the flow is completed.这导致密码管理器删除了现有的凭证,从而完成了流程。
windows 上一直在用 notepad++看日志,每次打开日志,可以全局搜索日志里面包含某个关键字的所有行。 并且 notepad++会自动在屏幕下面嵌入一个搜索结果窗口,包含这个关键字的所有行。点击某一行的时候,上面的正文也会自动的跳到这一行去,对查询日志非常方便。。。 不知道 mac 上有提供类似功能的 app 嘛。。。
或者同求有大神分享更好的 app 。。。
65 条回复 • 2021-04-06 10:16:21 +08:00
1
jobs03 天前 via iPhone 1
我一开始用 sublime,但是不支持 M1,现在用 vscode
2
qanniu3 天前
铜球。
看 log 楼主在春茧上班?
3
xylophone213 天前
同
4
nthin03 天前 via iPhone
同,想在 vscode 找个能实现类似功能到插件没找到
5
EZVIK3 天前
一开始用 atom, 后面打开程序太慢就改用 vscode 了, 直接 new 一个页面粘贴。
6
7v9TEc533 天前
010 editor
ultraedit
7
zhuxiaoxi3 天前 via iPhone
很少看日志,我记得 Mac 系统自带了一个工具。如果你想找搜索后结果单独显示点击结果,正文就能跳转的编辑器,可以试试 coteditor 。