ios学习过程

前言

        其实大学期间学的主要是java语言,java主流的框架像Spring,springmvc,mybatis,springboot都学过,项目实践也有一些。另外前端的话最基本的三门语言html5,css,js肯定也是java开发必须要了解的,同时也有jquery这些前端框架,也了解过vue这门框架。所以总的来说本科期间都是朝着后端开发的方向发展。

        只能说天不遂人愿,找工作稀里糊涂的来了ios开发,不过客户端开发也很有意思。至少不用管数据库那部分。

ios学习

        ios学习包括object-c语言和swift语言,现在主流的还是oc语言,但是swift语言肯定会之后作为ios开发的主要语言,一些三方库和swift底层是oc写的,因此至少也要能看懂oc,毕竟语言之间都大差不差。

        其实自学ios的人很少,为什么?我的理解第一个是因为设备问题。因为我们在上大学的时候,尤其是工科专业考虑软件兼容问题,大部分人都是选择PC,我身边用MAC的人也都是后面才换的,如果说其他方面比如说长期用apple产品的人肯定优先选择MAC,不乏有装逼的也用哈。这我就不得不吐槽一嘴,朋友圈两位大老爷们儿,对iPhone15各种尬吹,有种女生看到喜欢的男明星那种感觉。我最初用mac本也很生疏,最基本的一些操作都不清楚,触控板也玩不明白。另外,就我自学来看,ios开发自学免费的资源肯定是不如其他语言的,如果说不会科学上网更是如此。

基础部分

        基础部分其实语言与语言之间差别很小,大同小异吧。当然上swift中还是有很多新的地方。学习基础部分的前两天,能从这门语言中看到java,python,js的影子。和c语言还是有很大不同的,不过有一定的语言基础学起来很快,这点毋庸置疑。

        我相信很多人在学第一门语言的时候绝对知道菜鸟教程,所以基础部就是菜鸟教程,但是更加推荐使用苹果官方的教程。因为菜鸟教程就是抄的人家的,还不完整但也够用 Swift 教程 | 菜鸟教程       ​​​​​​关于 Swift | Swift 编程语言中文教程(The Swift Programming Language)

UIKit

        苹果后来出了swiftUI,但是初学者应该还是从uikit开始,这部分的资源极少,我用的一个比较老的,还是台湾的一个文档UIKit · Swift 起步走 这个教程有个缺点就是它已经老了,很多方法都被弃用了,需要自己去查查。

        这部分就和前端差不多了,学过前端的应该很容易上手。没什么好说的,就是跟着学,忘了的话再去查,回去看。我自己学习时候瞎写的如下:GitHub - 299710583/UIKitTest也用这个复习了下git

Cocoapods工具

        这个工具是用来管理三方库,ios开发中会用到一些很方便的三方库,这能够大大减少工作量,Cocoapods就是用来引入管理三方库的工具,类似maven管理工具。

        需要取下载和安装Cocoapods这个很多教程,照着做就能完成。

cocoapods首次使用三方库

  • 新建工程

  • 在终端进入工程文件夹

  • 终端输入pod init(安装了cocoapods的前提)

  • 编辑podfile文件,vi Podfile

  • 在Podfile文件中加入第三方库的依赖语法,保存退出

  • 终端输入Pod install

  • 完成之后,打开工程文件夹查看,打开.xcworkspace文件,完成!

常用的三方库

        Alamofire  和SwiftJSON

         alamofire这个库主要就是能够很方便用于网络请求。SwiftJSON这个三方库处理json非常方便,不用每一个都转化成[string?:any]的形式。具体的这个例子是一个天气的小demo不怎么规范,可以看下面网络请求部分,注释掉的就是用原始的方式请求:

//
//  WeatherData.swift
//  weather-demo
//
//  Created by 曾卫 on 2024/5/6.
//

import Foundation
import Alamofire
import SwiftyJSON

class WeatherData{
    var city: String?
    var url: URL?
    var json: [String:Any]?
    var weather: String?
    var temp_c: Int?
    var humidity: Int?
    var windDirection: String?
    var windSpeed: Double?
    var errors: String?
    var cityZh: String?
    var dates: [String]?
    var maxTemps: [Double]?
    var minTemps: [Double]?
    var weathers: [String]?
    var block: ((WeatherData) -> Void)?
    
    init(city: String?,cityZh:String?) {
        self.cityZh = cityZh
        self.city = city
        getWeatherData(city)
    }

    
}

extension WeatherData{
    func getWeatherData(_ city:String?){
        guard let city = city else { return }
        
        dates = []
        maxTemps = []
        minTemps = []
        weathers = []
        
        url = URL(string: "https://api.weatherapi.com/v1/forecast.json?key=2bedc09032474542ba132358243004&q=\(city)&days=7&aqi=no&alerts=no&lang=zh")!
        //        self.url = URL(string: "https://api.weatherapi.com/v1/current.json?key=2bedc09032474542ba132358243004&q=\(city)&aqi=no&alerts=no&lang=zh")
        
        guard let url = url else { return }
        
        //使用alamofire来实现
        
        AF.request(url).response { response in
            switch response.result{
            case .success(let value):
                let json = JSON(value!)
                //取出当前天气
                self.weather = json["current"]["condition"]["text"].string ?? " "

                self.temp_c = json["current"]["temp_c"].int ?? 0
                self.humidity = json["current"]["humidity"].int ?? 0
                self.windDirection = json["current"]["wind_dir"].string ?? " "
                self.windSpeed = json["current"]["wind_kph"].double ?? 0.0
                
                //取出预测天气
                if let array = json["forecast"]["forecastday"].array{

                    for item in array{
                        let element = JSON(item)
                        //取出日期
                        self.dates?.append(element["date"].string ?? "")

                        
                        //取出最高最低气温
                        self.maxTemps?.append(element["day"]["maxtemp_c"].double ?? 0.0)
//                        print(element["day"]["maxtemp_c"].double ?? 0.0)
                        self.minTemps?.append(element["day"]["mintemp_c"].double ?? 0.0)
                        //取出天气
                        self.weathers?.append(element["day"]["condition"]["text"].string ?? " ")
                        
                    }
                }
                self.block?(self)
                
            case .failure(let error):
                self.errors = error.localizedDescription
                print("Error: \(error.localizedDescription)")
                self.block?(self)
            }
        }
        
        
        //不使用alamofire
//        block?(self)
//
//        let request = URLRequest(url: url)
//        let session = URLSession.shared
//        let semaphore = DispatchSemaphore(value: 0)
//        let task = session.dataTask(with: request){ [self](data,response,error) in
//            if let error = error {
//                errors = "Error:\(error.localizedDescription)"
//                print(errors ?? " ")
//                
//            }
//            guard let httpResponse = response as? HTTPURLResponse,(200...299).contains(httpResponse.statusCode) else{
//                errors = "Error:Invalid response"
//                print(errors ?? " ")
//                semaphore.signal()
//                return
//            }
//            guard let data = data else{
//                errors = "Error:Miss data"
//                print(errors ?? " ")
//                semaphore.signal()
//                return
//            }
//            
//            do {
//                self.json = try JSONSerialization.jsonObject(with: data,options: []) as? [String:Any]
//                
//                //当前
//                let current = self.json?["current"] as? [String:Any]
//                //取出天气状态数据
//                let condition = current?["condition"] as? [String:Any]
//                let text = condition?["text"] as? String
//                self.weather = text
//                
//                // 取出温度
//                self.temp_c = current?["temp_c"] as? Int
//                
//                // 取出湿度
//                self.humidity = current?["humidity"] as? Int
//                
//                // 取出风向
//                self.windDirection = current?["wind_dir"] as? String
//                
//                // 取出风速
//                self.windSpeed = current?["wind_kph"] as? Double
//                //                print(self.windSpeed ?? "ddddd")
//                
//                semaphore.signal()
//                
//            }catch let parseError{
//                print("Error\(parseError.localizedDescription)")
//                semaphore.signal()
//            }
//        }
//        task.resume()
//        
//        semaphore.wait()
    }
}

SwiftPullToResfresh

        这个三方库用来实现下拉刷新,嘎嘎好使,用法也很简单。GitHub - WXGBridgeQ/SwiftPullToRefresh: An easy way to implement pull-to-refresh feature based on UIScrollView extension, written in Swift 4.An easy way to implement pull-to-refresh feature based on UIScrollView extension, written in Swift 4. - WXGBridgeQ/SwiftPullToRefreshicon-default.png?t=N7T8https://github.com/WXGBridgeQ/SwiftPullToRefresh/tree/master

       使用例子:

//下拉刷新,并且在里边写刷新要执行的是
        myScrollView.spr_setTextHeader {
            [weak self] in
            let label = UILabel()
            //这里之后要定义一个nextTime,用来记录最近更新时间
            label.text = "最近更新时间\(String(describing: self?.nextTime ?? " "))"
            let currentDate = Date()

            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "HH:mm:ss" // 仅保留时分秒部分
            self?.nextTime = dateFormatter.string(from: currentDate)
            
            label.textColor = .black
            label.textAlignment = .center
            label.frame = CGRect(x: 0, y: 10, width: 200, height: 20)
            label.tag = 123
            label.center = CGPoint(x: (self?.fullSize.width ?? 0) * 0.5, y: 10)
            label.font = UIFont.systemFont(ofSize: 14)
            
            self?.myScrollView.addSubview(label)
            self?.weatherData = WeatherData(city: self?.cityName,cityZh: self?.cityZh)
            self?.weatherData?.block = {[weak self] data in
                
                guard let `self` = self else { return }
                
                self.weatherData = data
                refresh()
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                self?.myScrollView.spr_endRefreshing()
                // 移除文字标签
                if let labelToRemove = self?.myScrollView.viewWithTag(123) {
                    labelToRemove.removeFromSuperview()
                }
                
            }
        }

AAInforgraphics

        这个三方库用来做图标也是非常好使的。

func drawChart(){
        chartView = AAChartView()
        chartView?.frame = CGRect(x: 0, y: 0, width: fullSize.width, height: fullSize.height * 0.4)
        chartView?.center = CGPoint(x: fullSize.width * 0.5, y: fullSize.height * 0.9)
        chartView?.isClearBackgroundColor = true
        guard let chartView = chartView else { return }
        self.myScrollView.addSubview(chartView)
        
        //初始化图标模型
        chartModel = AAChartModel()
        guard let chartModel = chartModel else { return }
        //图标类型
        chartModel.chartType(.line)
        //图表标题
        chartModel.title("天气预测")
        chartModel.inverted(false)
        chartModel.yAxisTitle("℃")
//        chartModel.xAxisTitle("日期")
        //浮动提示框
        chartModel.legendEnabled(true)
        chartModel.tooltipEnabled(true)
   
        chartModel.tooltipValueSuffix("℃")
        chartModel.markerRadius(0)
        chartModel.categories(weatherData?.dates ?? [])
        chartModel.colorsTheme(["#fe117c","#ffc069"])
        chartModel.series([
            AASeriesElement()
                .name("最高气温")
                .data(weatherData?.maxTemps ?? ["4","5"])
                .toDic()!,
            AASeriesElement()
                .name("最低气温")
                .data(weatherData?.minTemps ?? ["1","2"])
                .toDic()!])
        
        
        chartView.aa_drawChartWithChartModel(chartModel)
        
    }
    

其他

Xcode软件快捷键

ctrl + B:光标向左移动

ctrl + F:光标向右移动

ctrl + P:光标向上移动(up)

ctrl + N:光标向下移动(down)

ctrl + A:光标移动到最左边 (记忆,a为所有字母第一个)

ctrl + E:光标移动到最右边(记忆,end)

ctrl + K:删除光标右边的所有

ctrl + H:向左删除一个,和退格一样的

ctrl + D:删除右边一个,类似于反过来的删除键

cmd + 退格:删除从后边删除所有的左边。mac通用的

ctrl + A:光标移动到最左边 之后 ctrl + K:删除光标右边的所有 就可以删掉一整行

option + 退格:删除一个单词或者一个汉字组成的词(mac通用的)

ctrl + i:代码规范化

ctrl + V:向下移动一部分
cmd + L:跳转到具体行数的快捷键

git和sourcetree

git命令简单的还是记住,记不住就用sourcetree来,对新手很友好。

还是有就是沙盒机制,viewcontroller生命周期,怎么实现不走main.stroyboard,自定义首先打开的页面,不同页面之间怎么传递数据,用闭包和代理。

网上找到的大部分教程都是基于xcode11,12,13,这些教程对xcode15如何删除storyboard不完全有用。

在删除storyboard(教程看xcode11、12、13,是一样的)之后需要在SceneDelegate中改变func scene方法

否则黑屏

guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) let nav = UINavigationController() nav.pushViewController(ViewController(), animated: true) window.rootViewController = nav self.window = window window.makeKeyAndVisible()

但是AppDelegate这个我开始重写了里边的方法func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) ->

Bool 重写为

 

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. self.window = UIWindow.init(frame: UIScreen.main.bounds) self.window!.backgroundColor = UIColor.white self.window!.rootViewController = ViewController() self.window!.makeKeyAndVisible() return true }

正常用,但是后面我注释掉,直接返回true,依然可以正常操作。

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值