个人使用 SwiftUI 开发的“家乡税务管理应用”和创造的流动。

\点此安装/
Furusato税务管理应用程序-Furu Log-

Furusato税务管理应用程序-Furu Log-概述

《福禄日志》用于管理捐赠信息的备忘录应用程序是。
它是一个简单的应用程序,只执行简单的注册、查看、删除和计算。

●功能

  • 登记捐赠信息
  • 保持捐赠限额
  • 可以注册购买 URL
  • 识别已发送的一站式申请
  • 添加收藏夹按年份列出

【SwiftUI】ふるさと納税管理アプリ「ふるログ」の開発の全て!個人開発の流れ

【SwiftUI】ふるさと納税管理アプリ「ふるログ」の開発の全て!個人開発の流れ

是什么启发了我

根据积分的有无、处理方式、活动等,您在进行家乡纳税时购买的在线商店可能会有所不同。无法集中管理捐赠信息所以我想要一个管理应用程序。

开发环境

  • 语言:斯威夫特
  • 框架:Swift UI
  • 机器:MacBook Air
  • 开发环境:Xcode

Furu Log 是基于 Swift UI 开发做过。
苹果编辑使用官方提供的集成开发环境“Xcode”做过。

如何安装和使用 Xcode! Swift 和 SwiftUI 的区别

Furulog 开发流程和幕后花絮

如何管理数据

首先,决定如何管理数据。
由于这是一个备忘录应用程序,我们必须永久存储用户输入的数据。

在 Swift 中,即使应用程序停止,也有几种方法可以保留数据,但这次使用 JSON 进行文件管理我做到了

Swift 可以很方便的将 JSON 数据转换成结构,所以如果是简单的数据结构,也可以很方便的进行操作。

UserDefaults 在保存数据的功能方面
和 Realm Swift,如果你有兴趣,请看一下。

[SwiftUI] 什么是 Realm Swift?引入方法和CRUD处理方法

[SwiftUI] 什么是@AppStorage?如何在 UserDefaults 中保存数据

应用名称、图标等

  • 应用名称

"原木
“野之故乡”的“日志(历史)”

  • 图标
    故乡税的日本地图

  • 主题色
    Furusato = 老式图像 = 棕色

生产流程

我的应用程序开发流程如下。

  1. 定义模型数据
  2. 构建数据管理逻辑
  3. 构建视图以显示模型
  4. 链接视图(屏幕转换)
  5. 重构

    首先,我们定义了将在应用程序中处理的数据。 (我想我命名它是错误的......)

    • FuluLog结构:捐赠信息结构
    • UserDonationInfo 结构:用户的年度捐赠限额
    • AllFuluLog 类:在属性中保存一个“FuluLog 结构”格式的数组
    FuluLogModels.swift
    import Foundation
    
    
    struct FuluLog: Identifiable,Codable,Equatable {
    
        var id = UUID()             // 一意の値
        var productName:String      // 商品名
        var amount:Int              // 金額情報
        var municipality:String = ""// 自治体
        var url:String = ""         // URL
        var memo:String = ""        // メモ
        var request:Bool = false    // ワンストップ申請
        var time:String = ""        // 日付
    }
    
    
    struct UserDonationInfo:Identifiable, Codable,Equatable {
        var id = UUID()             // 一意の値
        var year:String             // 年
        var limitAmount:Int         // 上限金額
    
    }
    // MARK: -
    
    class AllFuluLog:ObservableObject{
        
        // MARK: - プロパティ
        @Published var allData:[FuluLog] = []  // 全情報
        // フィルタリング用
        @Published var timeArray:[String] = [] // 保存されている全年情報 ["2022","2023"]
        @Published var donationLimit:[UserDonationInfo] = [] // 年ごとの寄付金額の上限配列
        @Published var allFavoriteData:[FuluLog] = []  // お気に入り全情報
        
        init(){
            self.setAllData()
            self.createTimeArray()
            self.setAllDonationLimit()
            self.setAllFavoriteData()
        }
        
        // MARK: - プロパティセットメソッド
        func setAllData(){
            let f = FileController()
            self.allData = f.loadJson()
        }
        func setAllDonationLimit(){
            let f = FileController()
            self.donationLimit = f.loadDonationLimitJson()
        }
        func setAllFavoriteData(){
            let f = FileController()
            self.allFavoriteData = f.loadFavoriteJson()
        }
        // MARK: - プロパティセットメソッド
        
        // MARK: - メソッド
        // 寄付金上限リスト用
        func sumYearAmount(_ year:String) -> Int{
            var sum = 0
    
            let filterData = allData.filter({$0.time.prefix(4) == year })
            for data in filterData {
                sum += data.amount
            }
            return sum
        }
        
        // 登録制限
        func countAllData() -> Int{
            return self.allData.count
        }
        
        // timeArrayに保存されている全年情報を抽出した重複のない配列を構築
        func createTimeArray(){
            var array:[String] = ["all"]
            for item in allData {
                array.append(String(item.time.prefix(4)))
            }
            let timeSet = Set(array) // 重複値を除去
            self.timeArray = Array(timeSet).sorted().reversed()
        }
        // MARK: - メソッド
        
        // MARK: - CRUD
        func removeData(_ item:FuluLog) {
            guard let index = allData.firstIndex(of:item) else { return }
            allData.remove(at: index)
        }
        func updateData(_ item:FuluLog,_ id:UUID){
            guard let index = allData.firstIndex(where: { $0.id == id }) else { return }
            self.allData[index] = item
        }
        // MARK: - CRUD
      
        // MARK: - Donation CRUD
        func updateDonationLimit(_ item:UserDonationInfo,_ year:String){
            let f = FileController()
            guard let index = donationLimit.firstIndex(where: { $0.year == year }) else {
                // 今年未保存の場合 = 今年の年が無い場合
                // 新規データを保存処理
                f.saveDonationLimitJson(item)
                return
            }
            // 今年分保存済み = 今年の年がある場合
            // Update処理
            self.donationLimit[index] = item
            f.updateDonationLimitJson(self.donationLimit)
        }
        // MARK: - Donation CRUD
        
        // MARK: - Favorite CRUD
        func removeFavoriteData(_ item:FuluLog) {
            guard let index = allFavoriteData.firstIndex(of:item) else { return }
            allFavoriteData.remove(at: index)
        }
        func updateFavoriteData(_ item:FuluLog,_ id:UUID){
            guard let index = allFavoriteData.firstIndex(where: { $0.id == id }) else { return }
            self.allFavoriteData[index] = item
        }
        // MARK: - Favorite CRUD
    }
    

    数据管理逻辑

    由于您将处理文件以永久存储数据使用 FileManager 类的文件操作现在是必需的。

    [Swift] 使用 FileManager 保存文件!操作方法及存放地点

    通过在设备(文档文件夹)中创建一个文件并以 JSON 格式添加它来保留数据。

    此外,在 Swift 中,使用 JSONEncoder 类和 JSONDecoder 类结构⇆ JSON可以很容易地转换。

    [Swift] 如何编码 JSON 数据!如何使用 JSONEncoder 类

    [Swift] 如何解码 JSON 数据!如何使用 JSONDecoder 类

    我这样做是为了使这些进程可以作为一个文件(类)集中管理。

    构建视图以显示模型

    应用程序屏幕感觉标签在下边是分的,这在iOS应用中很常见我做到了

    内容视图是底层父视图我正在那里建立对孩子的一些看法。

    内容视图.swift
    import SwiftUI
    
    struct ContentView: View {
        // MARK: - View
        @State var selectedTag:Int = 1      //  タブビュー
        
        @ObservedObject var allFulu = AllFuluLog()
        
        init() {
               // リストの背景色を変更
               UITableView.appearance().backgroundColor = UIColor(named: "BaseColor")
           }
        
        var body: some View {
            TabView($selectedTag){
                
                // MARK: - Entry
                EntryFuluLogView().environmentObject(allFulu).tabItem{
                    Image(systemName:"plus.circle")
                }.tag(1)
                
                // MARK: - List
                ListFuluLogView().environmentObject(allFulu).tabItem{
                    Image(systemName:"list.bullet")
                }.tag(2)
                
                // MARK: - Favorite
                FavoriteFuluLogView().environmentObject(allFulu).tabItem{
                    Image(systemName:"star.fill")
                }.tag(3)
                
                // MARK: - Setting
                SettingView().environmentObject(allFulu).tabItem{
                    Image(systemName:"gear")
                }.tag(4)
                
            }.preferredColorScheme(.light)
            .accentColor(.orange)
            .ignoresSafeArea()
        }
    }
    

    创建子视图

    • 捐赠信息登记页面
    • 捐赠信息列表展示页面
    • 收藏夹列表页面
    • 设置页面

    重构

    什么是重构?改变代码而不改变行为“是。
    简而言之,就是杜绝浪费,清理代码。

    尽可能多地查看更细的划分使代码更可见我是受教的,所以我把它划分为业余爱好者。

    但是,有可以复用的视图,也有只是分割的视图。

    Furu Log 的源码发布在 GitHub 上,有兴趣的可以看看!

    GitHub-Furu 日志

    个人发展之流印象

    iOS 应用程序的个人开发按照以下流程进行。

    1. 定义您的应用概览
    2. 确定要准备哪些视图
    3. 提升必要的功能
    4. 实际生产
    5. 测试
    6. 已发布

      如果你自己做,你必须自己做所有的事情,所以有很多困难的部分,但是这个开发很有趣。

      没有什么比能够自己创建我想要的应用程序更让我开心的了。

      公开是要花钱的,而且就我而言,我也不是很了解,所以不知道能不能把它弄回来,但我想我积累了很多经验。

      我认为看到人们进行个人发展真是太棒了。


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308627627.html

相关文章: