俺、サービス売って家買うんだ

Swift, Kotlin, Vue.js, 統計, GCP / このペースで作ってればいつか2-3億で売れるのがポっと出来るんじゃなかろうか

Swift1.xで作ったアプリをSwift2.1に上げた時にでたコンパイルエラーたち

f:id:ie-kau:20151120074851p:plain


GWに作ったアプリを放置しっぱなしだったので、勉強がてらSwift2系統にアップデートした。その時に色々でたエラーに関するメモ。
アプリはこれ。

www.samurai-answer.com

自動でConvert Syntax

まずは、varをletに書きなおすとかは面倒くさいのでそのへんはXcodeに任せることにした。

f:id:ie-kau:20151120020109p:plain

そこから、出まくっていたコンパイルエラーを一つづつシューティング開始。

コンパイルエラー

a non-failable initializer cannot chain to failable initializer

class LevelUpView: UIView {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
class LevelUpView: UIView {
    required init(coder aDecoder: NSCoder) {
        super.init?(coder: aDecoder)
    }
}


'println' has been renamed to 'print'

printlnはなくなっています。

println('hoge')
print('hoge')


'CGImage?' is not convertible to 'AnyObject'; did you mean to use 'as!' to force downcast?

強制ダウンキャスト。(これってアップキャストなのでは?)

for var i = 0; i < 79; i++ {
    images.append(UIImage(named: "sprite_logo/\(i).png")!.CGImage as AnyObject)
}
for var i = 0; i < 79; i++ {
    images.append(UIImage(named: "sprite_logo/\(i).png")!.CGImage as! AnyObject)
}


Binary operator '|' cannot be applied to two 'UIRectCorner' operands

よくある角丸を作るコード。

var corner: UIRectCorner?
if isFirst && isLast {
    corner = (UIRectCorner.TopRight | UIRectCorner.TopLeft | UIRectCorner.BottomRight | UIRectCorner.BottomLeft)
} else if isFirst {
    corner = (UIRectCorner.TopRight | UIRectCorner.TopLeft)
} else if isLast {
    corner = (UIRectCorner.BottomRight | UIRectCorner.BottomLeft)
}
var corner: UIRectCorner?

if isFirst && isLast {
    corner = [UIRectCorner.TopRight, UIRectCorner.TopLeft, UIRectCorner.BottomRight, UIRectCorner.BottomLeft]
} else if isFirst {
    corner = [UIRectCorner.TopRight, UIRectCorner.TopLeft]
} else if isLast {
    corner = [UIRectCorner.BottomRight, UIRectCorner.BottomLeft]
}


Initialization of variable 'timer' was never used; consider replacing with assignment to '_' or removing it

警告だけど。

var timer = NSTimer.scheduledTimerWithTimeInterval(
    2.0,
    target: self,
    selector: Selector("next"),
    userInfo: nil,
    repeats: false
)
_ = NSTimer.scheduledTimerWithTimeInterval(
    2.0,
    target: self,
    selector: Selector("next"),
    userInfo: nil,
    repeats: false
)


Call can throw, but it is not marked with 'try' and the error is not handled

try!でエラーを無視できる。下の例だと音の話なので致命的な場所ではないのでエラー無視する書き方。

let audioPath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("bgm", ofType: "mp3")!)
self.bgmPlayer = AVAudioPlayer(contentsOfURL: audioPath, fileTypeHint: nil)
let audioPath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("bgm", ofType: "mp3")!)   
self.bgmPlayer = try! AVAudioPlayer(contentsOfURL: audioPath, fileTypeHint: nil)

stackoverflow.com


Cannot invoke initializer for type 'NSData' with an argument list of type '(contentsOfURL: NSURL, options: NSDataReadingOptions, error: inout NSError?)'

NSDあたの引数が変わってた。ここは手抜き対応。

var err: NSError?;
var imageData :NSData = NSData(contentsOfURL: url!,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)!;
let imageData = NSData(contentsOfURL: url!)


Value of type 'MFMailComposeResult' has no member 'value'

valueプロパティは大体rawValueに切り替わっている。enumの実体をとるときはこれ。

func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
      switch result.value {
      case MFMailComposeResultCancelled.value:
          print("Email Send Cancelled")
          break
      case MFMailComposeResultSaved.value:
          print("Email Saved as a Draft")
          break
      case MFMailComposeResultSent.value:
          print("Email Sent Successfully")
          break
      case MFMailComposeResultFailed.value:
          print("Email Send Failed")
          break
      default:
          break
      }
      
      self.mailViewController.dismissViewControllerAnimated(true, completion: nil)
  }
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
    switch result.rawValue {
    case MFMailComposeResultCancelled.rawValue:
        print("Email Send Cancelled")
        break
    case MFMailComposeResultSaved.rawValue:
        print("Email Saved as a Draft")
        break
    case MFMailComposeResultSent.rawValue:
        print("Email Sent Successfully")
        break
    case MFMailComposeResultFailed.rawValue:
        print("Email Send Failed")
        break
    default:
        break
    }
    
    self.mailViewController.dismissViewControllerAnimated(true, completion: nil)
}

stackoverflow.com


App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

セキュリティの強化でhttpが使えなくなったらしい。無理やり使うにはinfo.plistに以下をくわえる。

f:id:ie-kau:20151120021015p:plain

まとめ

間が空いたこともあり、大体一時間ぐらいで置き換えることができた。良かった・・