Apple Swift 공식 홈페이지

Swift - Apple Developer

 

Swift - Apple Developer

Swift는 iOS, macOS, tvOS 및 watchOS에서 사용할 수 있는 강력하면서도 직관적인 프로그래밍 언어입니다. Swift 코드 작성은 대화식으로 재미있고, 구문은 간결하면서도 표현력이 풍부하며, Swift에는 개

developer.apple.com

 

Swift.org

class와 structure 차이 검색하다 들어간 곳인데 스위프트에 대해 정리가 잘 되어있다.

Swift.org - Welcome to Swift.org

 

Swift.org

Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.

swift.org

그 중 일부 항목만 아래 링크 걸어두었고, 홈페이지에 가면 더 많은 자료를 얻을 수 있다.

 

Enumerations

Enumerations — The Swift Programming Language (Swift 5.3)

 

Enumerations — The Swift Programming Language (Swift 5.3)

Enumerations An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code. If you are familiar with C, you will know that C enumerations assign related names to a set of in

docs.swift.org

 

Structures and Classes

Structures and Classes — The Swift Programming Language (Swift 5.3)

 

Structures and Classes — The Swift Programming Language (Swift 5.3)

Structures and Classes Structures and classes are general-purpose, flexible constructs that become the building blocks of your program’s code. You define properties and methods to add functionality to your structures and classes using the same syntax you

docs.swift.org

 

Lexical Structure

Lexical Structure — The Swift Programming Language (Swift 5.3)

 

Lexical Structure — The Swift Programming Language (Swift 5.3)

Lexical Structure The lexical structure of Swift describes what sequence of characters form valid tokens of the language. These valid tokens form the lowest-level building blocks of the language and are used to describe the rest of the language in subseque

docs.swift.org

 

Expressions

Expressions — The Swift Programming Language (Swift 5.3)

 

Expressions — The Swift Programming Language (Swift 5.3)

Expressions In Swift, there are four kinds of expressions: prefix expressions, binary expressions, primary expressions, and postfix expressions. Evaluating an expression returns a value, causes a side effect, or both. Prefix and binary expressions let you

docs.swift.org

 

Tag. swift 자료, swift 정보, swift 정리, 스위프트 자료, 스위프트 정보, 스위프트 정리, 스위프트 도큐먼트, swift 도큐먼트, 스위프트 레퍼런스, swift 레퍼런스, swift 레퍼런스, swift reference

유료 앱으로는 Magic Utilities(Home - Magic Utilities)가 있다. 그런데 연결 디바이스 개수별로 매년 요금이 부과되는 구독형이고 금액이 만만치 않다... 사용하는 사람들 말로는 윈도우에서 이것만큼 완벽한게 없다고 한다... 그러니 저 돈을 받고도 팔리겠지;;

그 다음 유명한 것은 무료(?) 부문무료(?) 뭐 정확치는 않지만 Extra Magic(forBootCamp.org)이라는 앱이다. 설치도 까다로운데 생각보다 너무 구리다...

 

그리고 내가 선택한 것은!!!

깃허브(GitHub - imbushuo/mac-precision-touchpad: Windows Precision Touchpad Driver Implementation for Apple MacBook / Magic Trackpad)에 올라온 무료 앱이다.

 

지원 범위는 다음과 같다.

 

설치는 매우 간단하다.

sudo choco install mac-precision-touchpad -y

심지어 설정창도 없어서 설치가 되고 난 후에도 설치가 된지도 모른다. 설명에도 나와있듯이 맥북 내장이 아닌 매직 트랙패드 2는 USB 연결만 지원된다.

참고 : 4손가락 쓸어올리기 후 '데스크탑 추가'를 하면 맥에서처럼 네 손가락으로 좌우 넘기며 멀티 데스크탑을 사용할 수 있다. 단, 싱글모니터에서만.... 모니터가 2개 이상이면... 모든 모니터가 같이 좌우로 휙휙 넘어간다 -_-;; 게다가 버벅거리고...

 

해당 앱을 설치 후에는 필요 없는 제스쳐는 변경하거나 삭제하도록 한다.

물론... 맥에서의 트랙패드 만큼은 아니지만 적어도 윈도우 노트북에 내장된 트랙패드 하드웨어 품질이나 윈도우 상에서 트랙패드 작동 품질의 지옥에서 벗어나고 싶다면... 매직트랙패드 2 + precision은 매우 훌륭한 선택인 것 같다.

 

Tag. forbootcamp, forbootcamp.org, ForBootCamp, trackpad++, Trackpad++, ExtraMagic, extramagic, extra magic, magic utilities, magicutilities, Magic Utilities, MagicUtilities, 윈도우에서 애플 트랙패드, 윈도우에서 매직 트랙패드, 윈도우에서 매직트랙패드, 멀티 데스크탑, 가상 데스크탑, 화면 여러개, 데스크탑 여러개, 화면 여러 개, 데스크탑 여러 개

빌드를 하고 보면 Error는 아니지만 Warning이 어마어마하게 뜨는 것을 볼 수 있다.

클래스 내 attributes 타입을 ?을 붙여 nullable로 해줄 경우 #nullable enable이라고 명시해줘야 Warning이 뜨지 않는다.

class Program
{
    static void Main(string[] args)
    {
#nullable enable
        string? message = "Hello World";
#nullable disable
        string message2 = null;
    }
}

이런식으로 nullable 타입의 데이터는 위에 '#nullable enable'을 명시해주면 된다.

disable은 굳이 적을 필요 없다. 그냥 아래와 같이 쓰면 된다.

class Program
{
    static void Main(string[] args)
    {
#nullable enable
        string? message = "Hello World";
        string message2 = null;
    }
}

HTTP Strict-Transport-Security response header는 웹사이트가 웹 브라우저에게 HTTP 대신 HTTPS만을 사용하여 통신해야한다고 알리는 보안 기능을 말한다.

Web Server와 Web Browser가 모두 지원해야하며, 2010년도 이후 업데이트 된 브라우저라면 지원 된다고 보면 된다.

 

Apple, Google, Twitter, Amazon 같은 주요 사이트들은 브라우저에 기본으로 주소가 등록되어 자동으로 HTTPS로 연결이 되며, 그렇지 않은 경우 HTTP로 접속 시 서버에서 HTTPS로 접속하라고 HSTS 헤더를 전송하게 된다. 즉, 미리 등록된 사이트가 아니라면 최초 접속 이후부터 적용이 되는 것이다.

이렇게 자동 등록된 HSTS를 'Preloaded HSTS Lists'라고 한다는데... 내 브라우저엔 등록이 안 된 것 같다 -_-;;

 

기존에도 HTTP로 접속 시 웹 서버에서 HTTPS Redirection 응답을 보내는데 뭐가 다를까?

301, 302 Redirect은 서버에서 전송하는 것이다. 즉, 중간에 프록시가 있어 가로채더라도 클라이언트는 알 수가 없다. 하지만 HSTS를 사용하는 경우 307 Redirect를 하게 되는데 이는 브러우저 단에서 일어나는 Redirect이기 때문에 중간에 변조될 위험 없이 브라우저에서 바로 HTTPS로 접속을 보내게 된다.

 

Reference : www.searchenginejournal.com/google-on-307-hsts-redirects-http-to-https/386232/#close

 

Google on 307/HSTS Redirects (HTTP to HTTPS)

Google’s John Mueller explains how Googlebot interacts with HSTS redirects, also known as 307’s.

www.searchenginejournal.com

 

Tag. hsts header, hsts 헤더, HSTS header, HSTS 헤더

dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.67.dylib
  Referenced from: /usr/local/bin/node
  Reason: image not found

icu4u 버전 문제라고 한다.

brew uninstall --force node
brew uninstall icu4c && brew install icu4c
brew unlink icu4c && brew link icu4c --force
brew install node

 

자바 하다 C# 하면서 너무 짜증나는 것 중 하나가 클래스 기본 생성이 private로 된다는 것이다. 자바에서는 굳이 안 써도 패키지 내에서는 접근이 되었는데... 패키지 내에서 마저 접근이 안 되니 짜증이 난다...

그래서 바꾸기로 했다.

 

1. 파일 위치로 이동하기

Visual Studio 2019 기준으로 경로는 다음과 같다.

// Community version
C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/Common7/IDE/ItemTemplates/CSharp/Code/1033/Class

// Professional version
C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/ItemTemplates/CSharp/Code/1033/Class

permission으로 atom 등을 통해 수정이 되지 않는다. 하... 맥에서는 그냥 command + 'i' 누르면 permission 수정 되는데... 윈도우는 잘 모르겠다...

터미널을 이용해수정하자. (반드시 관리자 모드로 열어야 한다. sudo vim을 써서 열면 이상하게 새 파일로 열린다...)

// Community version
cd 'C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/Common7/IDE/ItemTemplates/CSharp/Code/1033/Class'

// Professional version
cd 'C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/ItemTemplates/CSharp/Code/1033/Class'

(저렇게 경로에 ' ' 를 넣어줘야지만 이동되더라...)

 

2. 파일 수정하기

해당 파일을 열어준다.

vim ./Class.cs

반드시 터미널은 관리자 모드로 열려야한다. 여기서는 이상하게 sudo vim을 해도 권한 부여되지 않고 새 파일로 열린다.

 

기존 파일의 형태다.

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;
$if$ ($targetframeworkversion$ >= 4.5)using System.Threading.Tasks;
$endif$
namespace $rootnamespace$
{
    class $safeitemrootname$
    {
    }
}

 

이렇게 public class로 고쳐서 저장한다.

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;
$if$ ($targetframeworkversion$ >= 4.5)using System.Threading.Tasks;
$endif$
namespace $rootnamespace$
{
    public class $safeitemrootname$
    {
    }
}

 

일단 dotnet 튜토리얼에서 지금까지 나온 것들을 정리해보면....

1. 문자열 리턴

public string Index() {
    return "HelloWorld Index String return";
}

return 타입 string

 

2. 변수를 문자열 처리해서 리턴

public string Welcome(string name, int ID = 1) {
    return HttpUtility.HtmlEncode("Hello " + name + ", ID is: " + ID);
}

return 타입 string
변수는 Http.Utility를 이용해 Html로 인코딩 해서 리턴

 

3. Razor로 페이지 리턴

public ActionResult Index() {
    return View();
}

문제는 이게 jsp처럼 서버에서 페이지를 html로 컴파일 해서 넘겨주는건지, html을 바로 넘겨주는건지 잘 모르겠다. 아마 html쪽 같아 보이기는 한데... 확장자는 또 왜 cshtml인건지;;

아무튼 return 타입은 ActionResult고 View()를 리턴한다고만 되어있다.

이 때도 역시 파일명을 따로 설정하지 않고 자동으로 매칭된다.

매칭되는 파일은 VIews/컨트롤러 이름/메소드이름.cshtml이 된다.

따라서 HelloWorldController의 Index 메소드의 View()에 의해 리턴되는 파일은 Views/HelloWorld/Index.cshtml이 된다.

Index.cshtml 파일은 다음과 같이 작성된다.

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@{ 
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

wktpgl qhaus자세히 보면 layout이 Views에 있는 다른 공유된 cshtml파일을 가리킨다. 거기에 이 페이지에서 추가한 코드 일부가 기본 탬플릿(?)같은 역할을 하는 레이아웃에 추가되서 완성된 페이지가 된다. (ViewBag.Title이라는거는 아래 레이아웃 페이지에 보면 <title></title>태그 사이에 @ViewBag.Title이라고 적혀있는 것을 볼 수 있을 것이다. 즉, 해당 변수를 "Index"라 하였으므로 탭에 표시되는 타이틀은 다음과 같다. 'Index - My ASP.NET Application')

참고로, _Layout.cshtml파일의 내용은 다음과 같다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

 

따라서 이런 페이지를 응답으로 받게 된다.

이 레이아웃에서 가장 중요한 부분은 '@RenderBody()'이란 annotation(?)이 있는 곳이다.

이곳에 각 Views에서 작성한 cshtml파일의 코딩 내용이 저 부분이 injection 되어 페이지가 완성된다.
(@ViewBag.Title처럼 정해진 위치로 가는 코드 제외)

위 코드를 조금 더 자세히 뜯어보면

<div class="navbar-collapse collapse">
  <ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("About", "About", "Home")</li>
    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
  </ul>
</div>

이런 코드가 보일것이다. 모든 페이지에 네비게이터를 추가해주는 코드이다. 

해당 메소드는 다음과 같은 역할을 한다.

음... 이렇게 보니 jsp 비슷한 건가보다... 서버에서 렌더링 해서 내려보내주는.... 아니 왜 최신 튜토리얼에서 이런 방식을...?? 프론트엔드/백엔드 완전히 나누는게 아니고 개발자가 디자인 빼고 다 하는... 완전 한국식인 것 같은데;;;

 

 

HomeController.cs는 프로젝트 생성 시 기본 생성된 홈컨트롤러고,
HelloWorldController.cs는 튜토리얼을 따라 만든 컨트롤러다.

각 파일들의 코드는 다음과 같다.

HomeCpontroller.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcMovie.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

 

HelloWorldController.cs

using System.Web;
using System.Web.Mvc;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        // 
        // GET: /HelloWorld/ 

        public string Index()
        {
            return "This is my <b>default</b> action...";
        }

        // 
        // GET: /HelloWorld/Welcome/ 

        public string Welcome()
        {
            return "This is the Welcome action method...";
        }
    }
}

뭔가 명시된 경로가 없다??????????

 

이는 다음 경로에 정의되어있다.

App_Start/RouteConfig.cs의 파일 내용 중 다음과 같은 코드가 있다.

namespace MvcMovie
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

(namespace는 자바의 package에 해당한다)

라우터를 다음과 같이 작동하도록 설정되어있다.

/[Controller]/[ActionName]/[Parameters]

그리고 미리 설명하자면
1 ) Index는 URL 입력 시 / 만 입력해도 들어가는 기본 경로로 지정되도록 되어있다.
2 ) 각 Controller의 이름은 'ㅇㅇㅇController'에서 'Controller'를 떼어낸 'ㅇㅇㅇ'만 해당된다.
3 ) 예외적으로 HomeController의 Index는 경로를 모두 생략시 최상위 URL 경로로 잡는다.

즉, HomeController의 Index 액션에 해당하는 URL 주소는
localhost:포트번호/
localhost:포트번호/home/
localhost:포트번호/home/index
3개에 매칭된다. (localhost:포트번호/index는 컨트롤러 이름을 생략해버려서 불가능하다. 즉, localhost:포트번호/ 이것만 예외인 경우다. 그 이유는 route.MapRoute에 defaults를 home/index로 정의해 놓았으니까!!!)

마찬가지로 HomeController의 About 액션에 해당하는 URL 주소는
localhost:포트번호/home/about
하나에 매칭된다.

 

마찬가지로, HelloWorldController의 Index 액션에 해당하는 URL 주소는
localhost:포트번호/helloworld/
localhost:포트번호/helloworld/index
2개에 매칭되고

HelloWorldController의 Welcome 액션에 해당하는 URL 주소는
localhost:포트번호/helloworld/welcome
하나에 매칭된다.

 

RouteConfig.cs에 들어올 파라미터를 미리 정의하기

일반적으로 GET방식 파라미터는 ? 뒤에 key-value 형태로 들어온다. 그 경우는 다음과 같다.

public string Welcome(string name, int ID = 1) {
    return HttpUtility.HtmlEncode("Hello " + name + ", ID is: " + ID);
}
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

즉, id라는 파라미터는 정의되어 있으나 optional이고, name은 파라미터를 써서 던져줘야한다.

그런데 라우터를 아래와 같이 하나를 더 추가하면

routes.MapRoute(
    name: "Hello",
    url: "{controller}/{action}/{name}/{id}"
);

이 경우 파라미터의 순서가 중요하다. ? 뒤에 파라미터를 직접 넣어줄 때는 순서가 필요 없지만 위에처럼 정의하면 아래와 같은 URL을 컨트롤러에 의해 ?뒤에 오는 파라미터가 아님에도 URL path 자체를 파라미터로 인식한다.

localhost:포트번호/helloworld/welcome/Tree/22

이런 URL을 원래대로라면 22까지 모두 path로 읽어야 하지만 welcome까지만 path로 읽고, Tree와 22는 각각 name=Tree, id=22라는 파라미터로 인식한다.

물론, 이렇게 라우터를 정의했더라도 ? 뒤에 파라미터를 직접 정의해 URL을 보낼 경우 Default 라우터에 의해 기존대로 잘 작동한다.

참고 : 라우터의 name은 식별하기 위한 것이지 동작에 영향을 주지 않는다. 영향을 주는 것은 url이다.

 

+ Recent posts