parent
c74e0d9041
commit
ad0e7b17c7
@ -0,0 +1,15 @@
|
||||
//
|
||||
// NSNotification+IndieMusic.swift
|
||||
// IndieMusic
|
||||
//
|
||||
// Created by WenLei on 2024/1/3.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Notification.Name {
|
||||
/// 城市改变
|
||||
static let notiWecahtResp = Notification.Name("notiWecahtResp")
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
//
|
||||
// UILabel+IndieMusic.swift
|
||||
// IndieMusic
|
||||
//
|
||||
// Created by WenLei on 2024/1/3.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
|
||||
extension UILabel {//富文本
|
||||
func addAttributed(attributedes: Array<(string: String, dic: Dictionary<NSAttributedString.Key, Any>)>) {
|
||||
|
||||
let attributedString = NSMutableAttributedString.init()
|
||||
|
||||
for attributed in attributedes {
|
||||
let attr = NSAttributedString.init(string: attributed.string, attributes: attributed.dic)
|
||||
attributedString.append(attr)
|
||||
}
|
||||
|
||||
self.attributedText = attributedString
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,170 @@
|
||||
//
|
||||
// UserDefaultKeys.swift
|
||||
// HuHeHaoTePolice
|
||||
//
|
||||
// Created by Willei Wang on 2018/5/7.
|
||||
// Copyright © 2018年 Willei Wang. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol UserDefaultsSettable {
|
||||
associatedtype defaultKeys: RawRepresentable
|
||||
|
||||
}
|
||||
|
||||
extension UserDefaultsSettable where defaultKeys.RawValue == String {
|
||||
|
||||
// set
|
||||
|
||||
static func set(_ value: String?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(value, forKey: aKey)
|
||||
}
|
||||
|
||||
static func set(_ value: Int?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(value, forKey: aKey)
|
||||
}
|
||||
|
||||
static func set(_ value: Bool?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(value, forKey: aKey)
|
||||
}
|
||||
|
||||
static func set(_ value: Double?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(value, forKey: aKey)
|
||||
}
|
||||
|
||||
static func set(_ value: Float?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(value, forKey: aKey)
|
||||
}
|
||||
|
||||
static func set(_ value: URL?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(value, forKey: aKey)
|
||||
}
|
||||
|
||||
static func set(_ value: Any?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(value, forKey: aKey)
|
||||
}
|
||||
|
||||
static func set<T: Encodable>(model: T?, forKey key: defaultKeys) {
|
||||
let aKey = key.rawValue
|
||||
UserDefaults.standard.set(model: model, forKey: aKey)
|
||||
}
|
||||
|
||||
|
||||
// get
|
||||
|
||||
static func string(forKey key: defaultKeys) -> String? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.string(forKey: aKey)
|
||||
}
|
||||
|
||||
static func integer(forKey key: defaultKeys) -> Int? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.integer(forKey: aKey)
|
||||
}
|
||||
|
||||
static func double(forKey key: defaultKeys) -> Double? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.double(forKey: aKey)
|
||||
}
|
||||
|
||||
static func bool(forKey key: defaultKeys) -> Bool? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.bool(forKey: aKey)
|
||||
}
|
||||
|
||||
static func float(forKey key: defaultKeys) -> Float? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.float(forKey: aKey)
|
||||
}
|
||||
|
||||
static func url(forKey key: defaultKeys) -> URL? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.url(forKey: aKey)
|
||||
}
|
||||
|
||||
static func object(forKey key: defaultKeys) -> Any? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.object(forKey: aKey)
|
||||
}
|
||||
|
||||
static func model<T: Decodable>(forKey key: defaultKeys) -> T? {
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.model(forKey: aKey)
|
||||
}
|
||||
|
||||
// remove
|
||||
static func remove(forKey key: defaultKeys){
|
||||
let aKey = key.rawValue
|
||||
return UserDefaults.standard.removeObject(forKey: aKey)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// 对UserDefaults扩展支持model存储
|
||||
extension UserDefaults {
|
||||
|
||||
func set<T: Encodable>(model: T?, forKey key: String) {
|
||||
if let model = model {
|
||||
let encoded = try? JSONEncoder().encode(model)
|
||||
UserDefaults.standard.set(encoded, forKey: key)
|
||||
} else {
|
||||
UserDefaults.standard.removeObject(forKey: key)
|
||||
}
|
||||
}
|
||||
|
||||
func model<T: Decodable>(forKey key: String) -> T? {
|
||||
if let data = UserDefaults.standard.data(forKey: key) {
|
||||
return try? JSONDecoder().decode(T.self, from: data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
extension UserDefaults {
|
||||
// 账户信息
|
||||
struct AccountInfo: UserDefaultsSettable {
|
||||
|
||||
enum defaultKeys: String {
|
||||
case userToken
|
||||
case userID
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct Setting: UserDefaultsSettable {
|
||||
enum defaultKeys: String {
|
||||
/// 是否开启Debug模式
|
||||
case isOpenDebug
|
||||
/// 当前的服务器地址
|
||||
case currentBaseUrl
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct CustomerInfo: UserDefaultsSettable {
|
||||
enum defaultKeys: String {
|
||||
case pushToken
|
||||
case isPrivacyPolicyAllowed
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
func removeAllDefaultKeys() {
|
||||
UserDefaults.AccountInfo.remove(forKey: .userID)
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
//
|
||||
// LaunchADManager.swift
|
||||
// IndieMusic
|
||||
//
|
||||
// Created by WenLei on 2024/1/3.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import XHLaunchAd
|
||||
|
||||
class LaunchADManager: NSObject, XHLaunchAdDelegate {
|
||||
|
||||
static let shared = LaunchADManager()
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
self.setupXHLaunchAd()
|
||||
}
|
||||
|
||||
// override init() {
|
||||
// super
|
||||
// }
|
||||
|
||||
func becomeActive() {
|
||||
self.setupXHLaunchAd()
|
||||
}
|
||||
|
||||
func setupXHLaunchAd() {
|
||||
photoAD()
|
||||
}
|
||||
|
||||
func photoAD() {
|
||||
XHLaunchAd.setLaunch(.launchScreen)
|
||||
XHLaunchAd.setWaitDataDuration(2)
|
||||
|
||||
//配置广告数据
|
||||
let imageAdconfiguration = XHLaunchImageAdConfiguration.init()
|
||||
imageAdconfiguration.duration = 4
|
||||
imageAdconfiguration.frame = CGRect.init(x: 0, y: 0, width: BaseDimensions.screenWidth, height: BaseDimensions.screenHeight)
|
||||
// imageAdconfiguration.imageNameOrURLString = adModel.mediaUrl ?? ""
|
||||
|
||||
//缓存机制(仅对网络图片有效)
|
||||
//为告展示效果更好,可设置为XHLaunchAdImageCacheInBackground,先缓存,下次显示
|
||||
imageAdconfiguration.imageOption = .cacheInBackground
|
||||
imageAdconfiguration.contentMode = .scaleAspectFill
|
||||
// imageAdconfiguration.openModel = adModel.pointTo ?? ""
|
||||
|
||||
//广告显示完成动画
|
||||
imageAdconfiguration.showFinishAnimate = .fadein
|
||||
//广告显示完成动画时间
|
||||
imageAdconfiguration.showFinishAnimateTime = 0.4
|
||||
//跳过按钮类型
|
||||
imageAdconfiguration.skipButtonType = .timeText
|
||||
// imageAdconfiguration.customSkipView = self.skipButton()
|
||||
//后台返回时,是否显示广告
|
||||
imageAdconfiguration.showEnterForeground = false
|
||||
|
||||
//图片已缓存 - 显示一个 "已预载" 视图 (可选)
|
||||
// if XHLaunchAd.checkImageInCache(with: URL.init(string: model.mediaUrl)) {
|
||||
// //设置要添加的自定义视图(可选)
|
||||
//// imageAdconfiguration.subViews = [self launchAdSubViews_alreadyView];
|
||||
// }
|
||||
|
||||
//显示开屏广告
|
||||
XHLaunchAd.imageAd(with: imageAdconfiguration, delegate: self)
|
||||
|
||||
|
||||
}
|
||||
|
||||
func skipButton() -> UIButton {
|
||||
let skipButton = UIButton.init(frame: CGRect.init(x: BaseDimensions.screenWidth - 100, y: BaseDimensions.topHeight, width: 85, height: 30))
|
||||
skipButton.titleLabel?.font = UIFont.systemFont(ofSize: 14)
|
||||
skipButton.layer.cornerRadius = 5.0
|
||||
skipButton.layer.borderWidth = 1.5
|
||||
skipButton.layer.borderColor = UIColor.lightGray.cgColor
|
||||
skipButton.backgroundColor = .gray
|
||||
skipButton.setTitleColor(.white, for: .normal)
|
||||
skipButton.addTarget(self, action: #selector(skipAction), for: .touchUpInside)
|
||||
skipButton.setTitle("跳过", for: .normal)
|
||||
return skipButton
|
||||
}
|
||||
|
||||
// @objc func skipButtonClick() {
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
/// 跳过
|
||||
@objc func skipAction() {
|
||||
XHLaunchAd.removeAnd(animated: true)
|
||||
}
|
||||
|
||||
// 点击事件
|
||||
func xhLaunchAd(_ launchAd: XHLaunchAd, clickAndOpenModel openModel: Any, click clickPoint: CGPoint) {
|
||||
/** openModel即配置广告数据设置的点击广告时打开页面参数(configuration.openModel) */
|
||||
|
||||
// let webVC = WebViewController.init(viewModel: nil, )
|
||||
// webVC.url = openModel as? String
|
||||
// MainRootVc?.children.first?.navigationController?.pushViewController(webVC, animated: true)
|
||||
}
|
||||
|
||||
|
||||
func xhLaunchAdShowFinish(_ launchAd: XHLaunchAd) {
|
||||
|
||||
|
||||
|
||||
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notiShowAD"), object: nil, userInfo: nil)
|
||||
|
||||
}
|
||||
|
||||
func xhLaunchAd(_ launchAd: XHLaunchAd, customSkip customSkipView: UIView, duration: Int) {
|
||||
var button = self.skipButton()
|
||||
//设置自定义跳过按钮倒计时
|
||||
button.setTitle("\(duration)跳过", for: .normal)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,176 @@
|
||||
//
|
||||
// AgreementViewController.swift
|
||||
// IndieMusic
|
||||
//
|
||||
// Created by WenLei on 2024/1/3.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class AgreementViewController: UIViewController {
|
||||
|
||||
let containerView: UIView = {
|
||||
let containerView = UIView.init()
|
||||
containerView.backgroundColor = .white
|
||||
containerView.layer.cornerRadius = 12
|
||||
|
||||
return containerView
|
||||
}()
|
||||
let bottomMenuView: UIView = {
|
||||
let bottomMenuView = UIView.init()
|
||||
|
||||
|
||||
return bottomMenuView
|
||||
}()
|
||||
|
||||
let titleLabel: UILabel = {
|
||||
let titleLabel = UILabel.init()
|
||||
titleLabel.textAlignment = .center
|
||||
titleLabel.font = UIFont.systemFont(ofSize: 16, weight: .medium)
|
||||
titleLabel.textColor = .init(hex: 0x323233)
|
||||
titleLabel.text = "阅读并同意以下协议"
|
||||
return titleLabel
|
||||
}()
|
||||
|
||||
let detailTextView: UITextView = {
|
||||
let detailTextView = UITextView.init()
|
||||
detailTextView.textAlignment = .center
|
||||
detailTextView.font = UIFont.systemFont(ofSize: 12)
|
||||
detailTextView.textColor = .init(hex: 0x323233)
|
||||
detailTextView.tintColor = UIColor.primaryText()
|
||||
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.alignment = .center
|
||||
paragraphStyle.lineSpacing = 5
|
||||
|
||||
detailTextView.addAttributed(attributedes: [("已阅读并同意 ", [NSAttributedString.Key.foregroundColor: UIColor.secondaryText(), NSAttributedString.Key.paragraphStyle: paragraphStyle]),
|
||||
("《用户协议隐私政策》", [NSAttributedString.Key.foregroundColor: UIColor.primaryText(), NSAttributedString.Key.link: URL.init(string: Configs.App.aggrementUrl) ?? "", NSAttributedString.Key.paragraphStyle: paragraphStyle, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12, weight: .medium)]),
|
||||
(" 并授权获取本机号码", [NSAttributedString.Key.foregroundColor: UIColor.secondaryText(), NSAttributedString.Key.paragraphStyle: paragraphStyle])
|
||||
])
|
||||
|
||||
return detailTextView
|
||||
}()
|
||||
|
||||
|
||||
let cancelButton: UIButton = {
|
||||
let cancelButton = UIButton.init()
|
||||
cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
|
||||
cancelButton.setTitle("取消", for: .normal)
|
||||
cancelButton.setTitleColor(UIColor.tertiaryText(), for: .normal)
|
||||
cancelButton.addTarget(self, action: #selector(cancelButtonClicked), for: .touchUpInside)
|
||||
|
||||
return cancelButton
|
||||
}()
|
||||
|
||||
let confirmButton: UIButton = {
|
||||
let confirmButton = UIButton.init()
|
||||
confirmButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
|
||||
confirmButton.setTitle("已阅读并同意", for: .normal)
|
||||
confirmButton.setTitleColor(UIColor.primaryText(), for: .normal)
|
||||
confirmButton.addTarget(self, action: #selector(confirmButtonClick), for: .touchUpInside)
|
||||
|
||||
return confirmButton
|
||||
}()
|
||||
|
||||
|
||||
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
|
||||
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
||||
|
||||
|
||||
self.modalPresentationStyle = .custom
|
||||
self.transitioningDelegate = self
|
||||
|
||||
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
makeUI()
|
||||
}
|
||||
|
||||
|
||||
|
||||
func makeUI() {
|
||||
|
||||
view.addSubview(containerView)
|
||||
containerView.addSubview(titleLabel)
|
||||
containerView.addSubview(detailTextView)
|
||||
|
||||
containerView.addSubview(bottomMenuView)
|
||||
bottomMenuView.addSubview(cancelButton)
|
||||
bottomMenuView.addSubview(confirmButton)
|
||||
|
||||
}
|
||||
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
|
||||
|
||||
containerView.snp.makeConstraints { make in
|
||||
make.size.equalTo(CGSize.init(width: 311, height: 174))
|
||||
make.center.equalTo(view)
|
||||
}
|
||||
|
||||
bottomMenuView.snp.makeConstraints { make in
|
||||
make.left.equalTo(containerView)
|
||||
make.right.equalTo(containerView)
|
||||
make.bottom.equalTo(containerView)
|
||||
make.height.equalTo(48)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(containerView).offset(26)
|
||||
make.left.equalTo(containerView).offset(24)
|
||||
make.right.equalTo(containerView).offset(-24)
|
||||
}
|
||||
|
||||
detailTextView.snp.makeConstraints { make in
|
||||
make.left.equalTo(containerView).offset(24)
|
||||
make.right.equalTo(containerView).offset(-24)
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(12)
|
||||
make.height.equalTo(40)
|
||||
}
|
||||
|
||||
cancelButton.snp.makeConstraints { make in
|
||||
make.left.equalTo(bottomMenuView)
|
||||
make.right.equalTo(bottomMenuView.snp.centerX)
|
||||
make.top.equalTo(bottomMenuView)
|
||||
make.bottom.equalTo(bottomMenuView)
|
||||
}
|
||||
|
||||
|
||||
confirmButton.snp.makeConstraints { make in
|
||||
make.right.equalTo(bottomMenuView)
|
||||
make.left.equalTo(bottomMenuView.snp.centerX)
|
||||
make.top.equalTo(bottomMenuView)
|
||||
make.bottom.equalTo(bottomMenuView)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@objc func cancelButtonClicked() {
|
||||
|
||||
}
|
||||
|
||||
@objc func confirmButtonClick() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extension AgreementViewController: UIViewControllerTransitioningDelegate {
|
||||
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
|
||||
|
||||
let carePresentationVC = CardPresentationController.init(presentedViewController: presented, presenting: presenting)
|
||||
carePresentationVC.viewType = .tips(false)
|
||||
|
||||
return carePresentationVC
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
//
|
||||
// BindPhoneViewModel.swift
|
||||
// IndieMusic
|
||||
//
|
||||
// Created by WenLei on 2024/1/3.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class BindPhoneViewModel: ViewModel, ViewModelType {
|
||||
|
||||
struct Input {
|
||||
|
||||
}
|
||||
|
||||
struct Output {
|
||||
|
||||
}
|
||||
|
||||
func transform(input: Input) -> Output {
|
||||
|
||||
return Output.init()
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "launch_icon.svg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "launch_slogn.svg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 308 KiB After Width: | Height: | Size: 8.1 MiB |
@ -0,0 +1,6 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#import "WXApi.h"
|
||||
#import "WXApiObject.h"
|
Loading…
Reference in new issue