Git Hub
коротко
Ctrl + ↑ Позднее

Паттерн Fabric Method

11 января 2017, 11:33

Оглавление

Фабричный метод

Фабричный метод порождает объекты одного и того же типа.

import Foundation
import UIKit

// Protocol for "Product" 
protocol AppleProduct {

    var name: String {get set}
    var screenSize: Double {get set}
    var price: Double {get set}

    func getProduct() -> String
}

// Protocl for "Creator" 
protocol AppleProductCreator {

    func createProduct() -> AppleProduct
}

// Class for "ConcreteProduct"
class IPhoneProduct: AppleProduct {

    var name: String = "iPhone 6"
    var screenSize: Double = 4.7
    var price: Double = 199.00

    func getProduct() -> String {

        return "Apple product "(name)", with screen size in (screenSize) inch, at proce: $(price)"
    }
}

class IPadProduct: AppleProduct {

    var name: String = "iPad Air 3"
    var screenSize: Double = 10.1
    var price: Double = 499.00

    func getProduct() -> String {

        return "Apple product "(name)", with screen size in (screenSize) inch, at proce: $(price)"
    }
}

// Class for "ConcreteCreator"
class IPhoneProductCreator: AppleProductCreator {

    static let sharedInstance:IPhoneProductCreator = IPhoneProductCreator()

    func createProduct() -> AppleProduct {

        return IPhoneProduct()
    }
}

class IPadProductCreator: AppleProductCreator {

    static let sharedInstance:IPadProductCreator = IPadProductCreator()

    func createProduct() -> AppleProduct {

        return IPadProduct()
    }
}

Применение

let product1: AppleProduct = IPhoneProductCreator.sharedInstance.createProduct()
print("Got a new device: " + product1.getProduct())

let product2: AppleProduct = IPadProductCreator.sharedInstance.createProduct()
print("Got a new device: " + product2.getProduct())

Пример 2

protocol Currency {
    func symbol() -> String
    func code() -> String
}

class Euro : Currency {
    func symbol() -> String {
        return "€"
    }

    func code() -> String {
        return "EUR"
    }
}

class UnitedStatesDolar : Currency {
    func symbol() -> String {
        return "$"
    }

    func code() -> String {
        return "USD"
    }
}

enum Country {
    case unitedStates, spain, uk, greece
}

enum CurrencyFactory {
    static func currency(for country:Country) -> Currency? {

        switch country {
            case .spain, .greece :
                return Euro()
            case .unitedStates :
                return UnitedStatesDolar()
            default:
                return nil
        }

    }
}

Применение

let noCurrencyCode = "No Currency Code Available"

CurrencyFactory.currency(for: .greece)?.code() ?? noCurrencyCode
CurrencyFactory.currency(for: .spain)?.code() ?? noCurrencyCode
CurrencyFactory.currency(for: .unitedStates)?.code() ?? noCurrencyCode
CurrencyFactory.currency(for: .uk)?.code() ?? noCurrencyCode

Pattern: Abstract Factory

11 января 2017, 11:19

Оглавление

Паттерн Абстрактная фабрика используется для обеспечения клиента набором родственных или зависимых объектов. «Семья» объектов, созданных на заводе-изготовителе определяются во время выполнения.


CoreData: Получение контекста

11 января 2017, 10:00

Получение контекста managedObjectContext в CoreData
Каждый объект хранимый в CoreData имеет ссылку на контекст

let context = someCoreDataItem.managedObjectContext

Паттерн Iterator

10 января 2017, 11:38

Оглавление

Пример

//: Playground - noun: Паттерн Iterator

import UIKit

struct BanksLevel{
    let price:Double
    let time:UInt32
    let comment:String
}

struct Levels {
    let arLevels: [BanksLevel]
}

struct LevelsIterator: IteratorProtocol {
    
    private var current = 0
    private let levels: [BanksLevel]
    
    init(levels: [BanksLevel]) {
        self.levels = levels
    }
    
    mutating func next() -> BanksLevel? {
        defer { current += 1 }
        return levels.count > current ? levels[current] : nil
    }
}

extension Levels: Sequence {
    func makeIterator() -> LevelsIterator {
        return LevelsIterator(levels: arLevels)
    }
}

Применение

let arLevels = Levels(arLevels: [
    BanksLevel(price: 1.06740, time: 1, comment: "Первый банковский уровень"),
    BanksLevel(price: 1.06210, time: 2, comment: "Второй банковский уровень")
] )

for level in arLevels {
    print("Определён: \(level)")
}

Пример 2

import UIKit



class Item{
    let name:String
    
    init(_ name:String){
        self.name = name
    }
}



class IteratableItems{
    var arItems: [Item] = []
    
    init(items:[Item]){
        self.arItems = items
    }
}

class ItemIterator: IteratorProtocol{
    private var current = 0
    private let arItems: [Item]
    
    init(items:[Item]){
        self.arItems = items
    }
    func next()-> Item?{
        defer {
             current += 1
        }
        return arItems.count > current ? arItems[current] : nil
    }
    
}

extension IteratableItems: Sequence {
    
    func makeIterator() -> ItemIterator {
        return ItemIterator(items: arItems)
    }
}

Используем:

let arItems = IteratableItems(items: [Item("One"),Item("Two"),Item("Three")])

for item in arItems{
    print("item: \(item.name)")
}

iOS: VIPER архитектура

26 декабря 2016, 13:44

Сделай настолько просто, насколько это возможно, но не проще.

(с)Альберт Эйнштейн

признаки хорошей архитектуры:

  1. сбалансированное распределение обязанностей между сущностями с жесткими ролями;
  2. тестируемость. Обычно вытекает из первого признака (без паники, это осуществимо при соответствующей архитектуре);
  3. простота использования и низкая стоимость обслуживания.

VIPER

Архитектура VIPER

Архитектура VIPER

Разделение обязанностей — это очень хорошо

View: отвечает за отображение данных на экране и оповещает Presenter о действиях
пользователя. Пассивен, сам никогда не запрашивает данные, только получает их от
презентера.

Interactor: содержит всю бизнес-логику, необходимую для работы текущего модуля.

Presenter: получает от View информацию о действиях пользователя и преображает ее
в запросы к Router’у, Interactor’у, а также получает данные от Interactor’a,
подготавливает их и отправляет View для отображения.

Entity: объекты модели, не содержащие никакой бизнес-логики.

Router: отвечает за навигацию между модулями.

Книга VIPER

Carthage: менеджер зависимостей

25 декабря 2016, 15:15

Carthage: менеджер зависимостей, как о нём говорят «простой и безжалостный»

carthage version

Cartfile — простой текстовый файл, который описывает зависимости Вашего проекта для Carthage, таким образом, он определяет, что устанавливать. Каждая строка в Cartfile указывает, откуда извлечь зависимость, имя зависимости, и при необходимости, какая версия зависимости используется. Cartfile аналогичный файлу Podfile в CocoaPods.

| Cartfile — создаём любым блокнотом

touch Cartfile
open -a Xcode Cartfile
github "CocoaLumberjack/CocoaLumberjack"
carthage update --platform iOS


Swift: Проверяем интернет соединение

6 декабря 2016, 11:23

Всегда в приложениях работающих с сетью стоит проверять наличие сети.

import Foundation
import SystemConfiguration

public class CheckInternet {
    class func isConnectedToNetwork() -> Bool {
        
        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
        
        let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
                SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
            }
        }
        
        var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
        if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
            return false
        }
        
        let isReachable = flags == .reachable
        let needsConnection = flags == .connectionRequired
        
        return isReachable && !needsConnection
        
    }

}
if (CheckInternet.isConnectedToNetwork() == true) {
    ...  // есть интернет
    }
    else{
   ...  // у вас нет интернета
    }

Swift: Animation

4 декабря 2016, 15:46

Анимацию элементов сделать довольно не сложно

Скрытие элементов

let step1 = 0.5
        let step2 = 1.0
        let step3 = 1.5
        
        UIView.animate(withDuration: step1, animations: {
            self.labelDate.alpha = 0
            self.view.layoutIfNeeded()
        })
        
        UIView.animate(withDuration: step2, animations: {
            self.labelLevelUP.alpha = 0
            self.view.layoutIfNeeded()
        })
        
        UIView.animate(withDuration: step3, animations: {
            self.labelLevelDN.alpha = 0
            self.view.layoutIfNeeded()
        })

Показ элементов

func showUI(){
        let step1 = 1.0
        let step2 = 2.0
        let step3 = 3.5
        
        UIView.animate(withDuration: step3, animations: {
            self.labelDate.alpha = 1
            self.view.layoutIfNeeded()
        })
        
        UIView.animate(withDuration: step2, animations: {
            self.labelLevelUP.alpha = 1
            self.view.layoutIfNeeded()
        })
        
        UIView.animate(withDuration: step1, animations: {
            self.labelLevelDN.alpha = 1
            self.view.layoutIfNeeded()
        })
        
    }

просто изменяем прозрачность, иногда можно использовать задержку, в основном потоке чтобы не заморачиваться с  дочерними, вызвав функцию sleep(в секундах)

sleep(3)

Перемещение объектов

uiViewedObject.view.center = CGPoint(x,y)

Swift: Загружем из XIB файла

3 декабря 2016, 15:52

UIView

let cell = Bundle.main.loadNibNamed("MenuCellDefault", owner: self, options: nil)?.first as! MenuCellDefault

MenuCellDefault — имя xib файла
загрузка nib файла

такой вариант подходит для UIView производных, но не годится для UIViewController

UIViewController

let globalTasksVC  = GlobalTasksVC(nibName: "GlobalTasksVC", bundle: nil)
        self.present(globalTasksVC, animated: true, completion: nil)

Swft: uiAlertView

1 декабря 2016, 9:07

Пример 1

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)

Пример 2

let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default){
            UIAlertAction in
                print("close")
        })
        
        self.present(alert, animated: true, completion: {
            print("show AlertMessage")
        })

Swift: Unit Test

30 ноября 2016, 23:06

Тесты

Правила написания тестов:

  1. Тестируем одно поведение (один тест тестирует одно поведение)

для того чтобы протестировать свои классы приложения нужно добавить в начало файла с тестами

@testable import PrjoectNameApp

где PrjoectNameApp — имя вашего iOS приложения/проекта

Памятка по методам

Всегда ошибка

XCTFail(@"always failed")

Равенство базовых типов

let primitive1:Int = 5
        let primitive2:Int = 5
        XCTAssertEqual(primitive1, primitive2)
}

Равенство с погрешностью базовых типов

let constOne:Float = 5.012
        let constTwo:Float = 5.014
        let accuracy:Float = 0.005
        XCTAssertEqualWithAccuracy(constOne, constTwo, accuracy: accuracy)

—-

Проверка на nil

id foo = nil;
    XCTAssertNil(foo, @"pointer:%p", foo);

—-

Проверка с задержкой по времени

XCTestExpectation *expectation = [self expectationWithDescription:@"block not call"];
    NSTimeInterval timeout = 1.0f;
    [expectation performSelector:@selector(fulfill)
                      withObject:nil
                      afterDelay:0.3f];
    [self waitForExpectationsWithTimeout:timeout
                                 handler:nil];

Тест асинхронного взаимодействия

func testNetModel(){
        var items:[Post] = []
        let expect = expectation(description: "Test net Model")
        let model = NetModel()
        model.npGetList({
            posts in
            items = posts
            expect.fulfill()
        })
        
        waitForExpectations(timeout: 4.0, handler: { error in
            if let error = error {
                XCTFail(error.localizedDescription)
            }
            
            let isLoaded:Bool = (items.count > 1)
            XCTAssertTrue(isLoaded)
            if isLoaded == false {
                print("posts: \(items)")
            }
            
        })
    }

—-

#iOS   Swift   Test

Swift: читаем куки

29 ноября 2016, 10:53

просто читаем куки

func readCookies(){
        
        if let cookies = HTTPCookieStorage.shared.cookies {
            for cookie in cookies {
                print("\n\n\(cookie)\n\n")
            }
        }
    }

ставим куки к запросу

...
 let request =  NSMutableURLRequest(url: url! as URL)
 let cookies = HTTPCookieStorage.shared.cookies
        for cookie in cookies! {
             request.setValue(cookie.value, forHTTPHeaderField: cookie.name)
        }
 webView.delegate = self
 webView.loadRequest(request as URLRequest)

Swift: выполнить код в основном потоке

27 ноября 2016, 23:55
DispatchQueue.main.async {
                let urlSmallImage = "https:" + smallImage.string!
                let url = NSURL(string: urlSmallImage)
                let data = NSData(contentsOf:url! as URL)
                self.profilePhoto.image = UIImage(data:data! as Data)
            }

Swift: преобразование опционального типа к строгому

25 ноября 2016, 15:04

(imageOption?.description)!

let imageOption = value[0].dictionary!["photo"]?.dictionary?["src"]?.dictionary?["small"]
                        let imageSmall = "https:" + (imageOption?.description)!

SQL примеры )

25 ноября 2016, 0:03

Магазин: Корзина

17 ноября 2016, 10:00

Корзина


Swift: Изменить цвет векторной картинки pdf

8 ноября 2016, 9:43

Часто требуется изменить цвет отрисовки контурной иконки, в Swift 3 это делается так

let logo = UIImage(named: "Home")
let imageView = UIImageView(image:logo)
imageView.image = imageView.image!.withRenderingMode(.alwaysTemplate)
imageView.tintColor = UIColor.white
self.navigationItem.titleView = imageView

Получить минимальную цену товара в разделе

7 ноября 2016, 15:04
function getMinPriceBySectionID($sectionID){

    $CATALOG_ID = 4;
    $rsProducts = CIBlockElement::GetList(
        Array('CATALOG_GROUP_1' => 'ASC'),
        Array('IBLOCK_ID' => $CATALOG_ID, 'SECTION_ID' => $sectionID),
        false,
        Array('nTopCount' => 1),
        Array('IBLOCK_ID', 'ID', 'NAME', 'CATALOG_GROUP_1')
    );

    $arProducts = $rsProducts->Fetch();

    $price = $arProducts["CATALOG_PRICE_1"];
    if (!empty( $price))
         return App::priceFormat($price);
    else
        return false;
}

UIButton: скруглёные края

7 ноября 2016, 13:21
layer.cornerRadius   Number  10
layer.masksToBounds Boolean Yes
Ctrl + ↓ Ранее