SwiftUI 如何让view强制支持横屏或竖屏

问题:有时候在编写APP时,我们会需要某个页面只支持手机的某个方向(并不是懒得适配,确信)。而在swiftUI中,要实现这个设定又变得更加复杂了,本篇文章就希望提供一个清晰且简单的解法,来支持这一点。

首先,我们需要swiftUI支持AppDelegate.

在非swiftUI中,这个文件是在创建项目的时候就会被系统一同创建的,但swiftUI并没有为我们创建这个文件,但这并不意味着swiftUI就无法连接到AppDelegate并作出响应

而其实建立连接也十分简单,首先,创建一个class,这里其实创建AppDelegate的任何方法都可以,但为了不重复赘述,我这里直接写好了后面屏幕方向设定会用到的方法

class AppDelegate: NSObject, UIApplicationDelegate {
static var orientationLock = UIInterfaceOrientationMask.portrait

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}
}

这个设定,是将APP支持的屏幕方向设置了只支持竖屏,当然,如果你的APP也仅仅想做到这一步,那其实在设置里也可以直接做到,不用专门写一个class

接下来,在某个我们希望只支持横屏的view中,只要写下如下代码,即可切换到横屏

import SwiftUI

struct DestinationView: View {

var body: some View {
Group {

Text("Hello")

}.onAppear {
AppDelegate.orientationLock = UIInterfaceOrientationMask.landscapeLeft
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
.onDisappear {
DispatchQueue.main.async {
AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
}
}

要注意的是,UIDevice中设定Value时要使用rawValue,否则会报错,而在onDisappear方法中,要使用异步来保证当前view消失时,不会因为之前的view的屏幕朝向不同而报错

SwiftUI CoreData entity/实体更新导致无法预览的问题

最近改动了某个entity的类型,取消了它的继承,preview突然就停止工作了,一直提示crash,直接调用以下方法,清除之前的preview设定即可,因为preview里还保存了旧的设定,与新设定冲突,导致preview crash

xcrun simctl --set previews delete all

iOS开发如何浏览模拟器中的coredata数据

在后端开发使用go语言时,网络包的使用经历了beego,fasthttp等包,最终又用回了go的官方http包(当然这个包最近各种升级例如支持了优雅退出啊等等就算是另一说了),发现还是尽量用官方的东西更好一些。

iOS开发也是这样,iOS开发中本地数据库操作也有不少的解决方案,从iOS自带的coredata,到FMDB,再到完全不依赖sqlite的Realm,我原本也使用了一段时间的realm,但有两点让我很不爽

  1. 毕竟是第三方项目,总是要更新,如果你是使用OC语言的,那么还好,但如果你是像我一样使用swift语言的,那么swift的更新外加realm自身的更新能够把你烦死
  2. realm对于字段变更的操作非常不友好,如果还没生成数据还则罢了,如果已经生成了数据,那么不好意思,请按照realm提供的反人类一样的方法一步一步执行,而且你还得关注当前的字段版本,比如最老的版本是1.0,之后你又推出了1.0.1和1.0.2的更新,那么你就至少得写下1.0到1.0.2和1.0.1到1.0.2的两个版本迁移的代码块,因为我们是在面向C端的,你永远不知道你的用户什么时候更新你的APP,所以你得提供所有老版本到最新版本的转化方式。

综上,最终我还是决定用回coredata,至少官方的支持还是可以的,swift版本也不用像OC一样需要几个步骤生成连接代码等等,直接在model文件里操作好,背后的一切工作swift都已经帮你完成了,当然,这里我要强调一点,那就是本地数据库并不应该存储多么巨大复杂的数据,如果一个用户一天在你的APP里生成10条数据,一年也不到4000条,完全到不了需要拼速度和优化的时候。

终于说到正题,既然使用了coredata,那么调试的时候免不了会想要查看一下数据或者手动更改数据,可是模拟器的数据一是藏得深,二是并没有直接浏览更改的方式,我们分别解决一下。

获取数据路径

在AppDelegate文件的didfinishlaunch中加入下面这一行代码

print(FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask))

这样会把当前模拟器的文件路径打印出来,有了路径,就好办了,比如可以在terminal里直接open,然后应该会看到一个名为“Application Support”的文件夹,里面就是对应的.sqlite文件

查看.sqlite文件

有了文件,如何查看又是个问题,下面提供以下几个方法,可以根据自身情况自由选择

  • (推荐)使用sqlite3直接在terminal里查看
    • 对于习惯于用命令行操纵MySQL的人来说,sqlite3的操作应该没有什么入门难度,也是比较推荐的方法,Mac又是自带Python和sqlite3的,如果找不到,那么可以从如下网站来进行安装:https://www.sqlite.org/download.html
  • (推荐)可视化方案:DB Browser for SQLite
    • 对于习惯于可视化管理的人来说,我推荐这个方案,本身是一个在GitHub上的开源项目,马上要突破1万星,安全和可靠性都有保障,还是免费的,只要把.sqlite文件拖到这个APP内就可以自动打开,当然coredata自动命名的表名和你自己命名的略有区别,比如我创建了一个Objectives的Enity,在这里看到就是ZOBJECTIVES,自己找一下就可以了
    • GitHub地址:https://github.com/sqlitebrowser/sqlitebrowser
    • 官方网页直接下载打包好的版本:https://sqlitebrowser.org
  • 可视化方案:Base 2
    • 功能更完善,界面更好看,但没有优先推荐的原因是其是收费的,20欧的售价其实并不算高,不过没有特别专业复杂的需求,用上面的就足够了
    • 官网地址:https://menial.co.uk/base/
  • 可视化方案:Firefox sqlite插件
    • 这个大概就是特定适合使用火狐浏览器的人群了吧,我本身不用火狐,所以各位如果用的也可以测试了给我反馈一下
  • (不推荐尝试)可视化方案:Core-Data-Editor
    • 同样是GitHub上的一个开源方案,但由OC写成,同时也只支持OC,同时需要有一个初始的适配过程,并且不能直接打开.sqlite文件
    • GitHub地址:https://github.com/ChristianKienle/Core-Data-Editor

CocoaPods 1.1.0无法更新老项目中原有Target的解决办法

更新了Xcode8之后,重新打开好久没维护的一个项目,结果发现Alamofire4.X和iOS10以前的版本并不兼容,一狠心,不兼容9.X系列了。

安装Alamofire4.X需要CocoaPods 1.1.0,更新了pod之后我发现执行pod install的时候一直提示我的extension target需要host target,Google了各种解决办法也都没有解决,最终尝试了stackoverflow里看到的一条评论的方法:将老的target删了之后再重新添加,最终解决问题。。

应该算个比较笨的方法吧,不过也算是解决了问题。

Xcode8中无法设定extension图标的解决办法

更新了Xcode8之后一直在忙公司的项目,现在才得空照顾下自己的APP,我的APP有一个action extension的Target,先是pod抽风安不上库了,后来又发现图标找不到了。后来发现原来设置图标的位置被苹果转移了

wechatimg7

没错,转移到了Build setting里了。。

但是我在找到了解决方法之后又遇到了问题,就是根本没有这一项啊!!后来经过我自己摸索,发现需要先在Copy bundle resources里面加入你存有图标的Asset,然后这一项会自动出现。。

真是服了Apple的程序员,是觉得以前设置图标的方式不符合探索精神么。。