2015年5月29日 星期五

簡單整合原生的Camera拍照功能(swift)

要先在class宣告中加入下列兩個Delegate
UIImagePickerControllerDelegate, UINavigationControllerDelegate

在你要用來trigger的function中寫
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {
            var cameraCaptureController = UIImagePickerController()
            cameraCaptureController.delegate = self
            cameraCaptureController.allowsEditing = true
            cameraCaptureController.sourceType = UIImagePickerControllerSourceType.Camera
            self.yourParentViewController?.presentViewController(cameraCaptureController, animated: true, completion: nil)
        }

最後再實作你的Delegate
//MARK: UIImagePickerControllerDelegate, UINavigationControllerDelegate
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
        dismissCameraCaptureController(picker)
        //TODO: Pick camera capture here
        if let chosenImage = info[UIImagePickerControllerEditedImage] as? UIImage {
            //TODO: use chosenImage here
        } else {
            //TODO: Alert no picture selected.
        }
    }
    
    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        dismissCameraCaptureController(picker)
    }
    
    private func dismissCameraCaptureController(picker: UIImagePickerController) {
        picker.dismissViewControllerAnimated(true) { }
    }

2015年5月15日 星期五

一些設計原則

//global variable class 存取原則
  • 最好以某個專門負責的class(例如,web api)來作為唯一的修改點,其他地方都直接唯讀取用。
  • 如果是要存放修改點在其他class的變數,則要另外設local variable在修改完成後再直接copy過去
  • 如果不得已非要多方存取與修改時,則要設為synchonize以免在存取的中途被修改。

//TableViewCell 設定原則
  • 不要用同一種cell去換成新的UI style
  • 要針對各種不用的style去設計不同的cell來用
  • 用在viewController決定你要用什麼cell,把style obj傳入tableView中

//集合元素的設計原則
  • 不要在多對一之後,再一對多
  • 要把多個物件加入在同一個集合元素時,先把多組key統一整理成同一個唯一碼,再用這組唯一碼來還原為一對多。

//儘量避免函數副作用
  • side effects是有特別定義的,在IT中專指你的function會對呼叫它的地方造成影響。
  • 例如,函數被呼叫時會改動到全域變數,或是你用了inout參數,讓你的function可以直接改動它的輸入參數。
  • 比較好的作法
    • 儘量少用沒有參數的函數,因為這通常代表它會改動到全域變數。
    • 儘量讓每個函數都只實作輸入參數跟輸出之前轉換的邏輯。
//在swift 2.0之後,應該要優先使用struct和enum,需要繼承的時候再用class
  • swift 強化了struct和enum的功能,可以實踐class的大部份功用。
  • 原來的root class也可以用protocol加上protocol extension來實踐
  • 特別是要用RxSwift的時候,因為會用到大量的closure,struct可以確保線程安全。

//用struct的時候不要用到mutating來宣告function
  • swift的實作上struct的self物件是immutable的,所以如果你用了mutating,它會幫你再包一層操作,最後還是把你輸入的修改值重新new一個新的instance給你。

//RxSwift設計原則:如果可以,就別在viewModel中用subscribe
  • There are ideally no Variables, Subjects ....
  • There are no subscribe, bind, drive methods or subscriptions being made in any way.
  • Everything is just a definition. 
    • Because there are no subscriptions, there are no DisposeBags, etc .., no resource management is needed because all operators are already chaining disposing mechanism.
  • Everything is decoupled from the UI, there are no UIElements there, only pure logic

2015年4月24日 星期五

在textField輸入時,即時抓取text

//要用stringByReplacingCharactersInRange把textField delegate的回傳值給拚起來

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        var username = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
        if self.checkUsernameRule(username) {
            self.submitButton.enabled = true
        } else {
            self.submitButton.enabled = false
        }
        
        // return NO to not change text
        return true

    }

func checkUsernameRule(username: String) -> Bool {
        //Username should be 6–20 characters long, and start with a letter
        println(username)
        if username =~ "^[a-zA-Z]{1}(\\w{5,20})$" {
            return true
        }
        return false
    }

2015年4月23日 星期四

swift inout 參數

swift會把參數都用let來設,如果要改變參數原來的值的話,就要把參數設inout。

2015年4月15日 星期三

build app指令

xcodebuild clean archive -scheme migme-debug -workspace iOSClient.xcworkspace -archivePath archive/migme.xcarchive -destination generic/platform=iOS
mkdir -p ipa

xcodebuild -exportArchive -archivePath archive/migme.xcarchive -exportPath ipa/migme.ipa -exportProvisioningProfile "migme adhoc distribution"

2015年4月14日 星期二

計算NSAttributedString的size

如果用先new好的textview來放,就會一直失敗
internal func calculateTextSize(attributedText: NSAttributedString, maxWidth: CGFloat) -> CGSize {
        var measureTextView = UITextView()
        measureTextView.attributedText = attributedText
        let size = measureTextView.sizeThatFits(CGSizeMake(maxWidth, CGFloat(FLT_MAX)))
        return size

    }