> ## Documentation Index
> Fetch the complete documentation index at: https://developer.box.com/llms.txt
> Use this file to discover all available pages before exploring further.

# APIコールの実行

export const Link = ({href, children, className, ...props}) => {
  const localizedHref = localizeLink(href);
  return <a href={localizedHref} className={className} {...props}>
      {children}
    </a>;
};

export const ProgressBar = ({pages = [], ...props}) => {
  const [currentStep, setCurrentStep] = useState(0);
  const [isDarkMode, setIsDarkMode] = useState(false);
  useEffect(() => {
    const checkDarkMode = () => {
      const isDark = document.documentElement.classList.contains('dark');
      console.log('ProgressBar - isDarkMode:', isDark);
      setIsDarkMode(isDark);
    };
    checkDarkMode();
    const observer = new MutationObserver(() => {
      checkDarkMode();
    });
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => {
      observer.disconnect();
    };
  }, []);
  useEffect(() => {
    if (pages.length > 0) {
      const currentPath = window.location.pathname;
      const stepIndex = pages.findIndex(page => {
        const pagePath = page.startsWith('/') ? page : `/${page}`;
        return currentPath.endsWith(pagePath) || currentPath.includes(pagePath);
      });
      if (stepIndex !== -1) {
        setCurrentStep(stepIndex + 1);
      }
    }
  }, [pages]);
  if (!pages || pages.length === 0) {
    return null;
  }
  const step = currentStep;
  const total = pages.length;
  console.log('ProgressBar - Rendering with isDarkMode:', isDarkMode);
  const progressBarContainerStyle = {
    width: '100%',
    marginBottom: '32px',
    display: 'flex',
    alignItems: 'center',
    gap: '16px'
  };
  const stepsContainerStyle = {
    display: 'flex',
    alignItems: 'center',
    gap: '8px',
    flexShrink: 0
  };
  const progressBarTrackStyle = {
    flex: 1,
    height: '22px',
    backgroundColor: 'rgba(169, 210, 244, 0.06)',
    border: isDarkMode ? '1px solid rgba(230, 241, 247, 0.67)' : '1px solid #e3ecf3',
    borderRadius: '4px',
    overflow: 'hidden',
    position: 'relative'
  };
  const progressBarFillStyle = {
    height: '100%',
    backgroundColor: 'rgba(113, 192, 248, 0.23)',
    width: `${step / total * 100}%`,
    transition: 'width 0.3s ease'
  };
  const getStepStyle = (stepNumber, isActive) => {
    if (isDarkMode) {
      return {
        width: '22px',
        height: '22px',
        borderRadius: '4px',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: '12px',
        fontWeight: '600',
        position: 'relative',
        zIndex: 1,
        transition: 'all 0.3s ease',
        backgroundColor: isActive ? 'rgba(113, 192, 248, 0.23)' : 'transparent',
        color: isActive ? '#60a5fa' : '#a0aec0',
        border: isActive ? '1px solid #e3ecf3' : '1px solid #e0e6eb',
        cursor: 'pointer',
        textDecoration: 'none'
      };
    }
    if (isActive) {
      return {
        width: '22px',
        height: '22px',
        borderRadius: '4px',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: '12px',
        fontWeight: '600',
        position: 'relative',
        zIndex: 1,
        transition: 'all 0.3s ease',
        backgroundColor: 'rgba(169, 210, 244, 0.32)',
        color: '#374151',
        border: '1px solid #e1eef8',
        cursor: 'pointer',
        textDecoration: 'none'
      };
    }
    return {
      width: '22px',
      height: '22px',
      borderRadius: '4px',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontSize: '12px',
      fontWeight: '600',
      position: 'relative',
      zIndex: 1,
      transition: 'all 0.3s ease',
      backgroundColor: '#fbfbfb',
      color: '#9ca3af',
      border: '1px solid #e3ecf3',
      cursor: 'pointer',
      textDecoration: 'none'
    };
  };
  return <div style={progressBarContainerStyle} {...props}>
      <div style={stepsContainerStyle}>
        {Array.from({
    length: total
  }, (_, index) => {
    const stepNumber = index + 1;
    const pageIndex = index;
    const pagePath = pages[pageIndex];
    const fullPath = pagePath.startsWith('/') ? pagePath : `/${pagePath}`;
    const isActive = stepNumber === step;
    return <a key={stepNumber} href={fullPath} style={getStepStyle(stepNumber, isActive)}>
              {stepNumber}
            </a>;
  })}
      </div>
      <div style={progressBarTrackStyle}>
        <div style={progressBarFillStyle}></div>
      </div>
    </div>;
};

<ProgressBar
  pages={[
                    "guides/mobile/ios/quick-start/create-ios-app",
                    "guides/mobile/ios/quick-start/install-ios-sdk",
                    "guides/mobile/ios/quick-start/configure-box-app",
                    "guides/mobile/ios/quick-start/make-api-call",
                    "guides/mobile/ios/quick-start/next-steps"
                  ]}
/>

BoxアプリケーションとiOSアプリケーションが**Box iOS SDK**を使用して作成、設定されたら、初めてのBox APIコールを実行できるようになります。

空のiOSアプリケーションを使用して、現在認証されているユーザーの名前を取得するためのリクエストをBoxに対してトリガーするボタンを作成します。

<Warning>
  これらの例で使用されているブロックアクションを使用した場合、処理は遅くなります。本番アプリでは、これらのブロックアクションを適切なタスク委任アクションやブロック以外のアクションに置き換える必要があります。
</Warning>

## ボタンの作成

XcodeのSwiftアプリケーション内で、`ContentView.swift`を読み込みます。ファイルの先頭に`ContentView`の`struct`が表示されます。その中には、アプリをエミュレータで実行した場合にiOSアプリケーションに出力される基本の文字列があります。

```swift theme={null}
import SwiftUI

struct ContentView: View {
  var body: some View {
    Text("Hello, World!")
  }
}
```

最初に、現在のユーザーを取得するための呼び出しをトリガーできるように、`Text`の出力行をボタンに置き換えます。その行を以下のボタンに置き換えます。

```swift theme={null}
Button(action: {
  // Perform some action
}) {
  Text("Click to get current user")
}
.padding(10)
.cornerRadius(20)
.foregroundColor(.white)
.background(Color.blue)
```

次の手順では、Boxからユーザーの詳細を取得するアクションをボタンに追加します。

## APIコールのボタンアクションの追加

ユーザーがボタンをクリックしたときに、ユーザーの詳細が取得されるようにします。そのためには、**Box iOS SDK**のインポートを追加することと呼び出しを実行するボタンアクションを追加することという2つの処理が必要です。

`ContentView.swift`ファイルの先頭に、他のimportステートメントとともに`import BoxSDK`を追加します。

次に、現在はコメントのプレースホルダがあるボタンアクション内に、現在のユーザーを取得するためのiOS SDKへの呼び出しを追加します。APIコールが完了すると、開発者コンソールに認証メッセージが出力されます。実装を容易にするため、処理をブロックする`sleep(5)`コールを配置しています。これは、リクエストが完了するのに十分な時間をとることで、Box iOS SDKから呼び出しを実行できるかどうかをテストするためです。

`{{YOUR DEVELOPER TOKEN}}`を実際の開発者トークンに置き換えます。

```swift theme={null}
let client = BoxSDK.getClient(token: "{{YOUR DEVELOPER TOKEN}}")

client.users.getCurrent(fields:["name", "login"]) { (result: Result<User,
  BoxSDKError>) in
  guard case let .success(user) = result else {
      print("Error getting user information")
      return
  }
  print("Authenticated as \(user.name)")
}

sleep(5)
```

iOSエミュレータでサンプルアプリケーションをビルドして実行します。

<Warning>
  最後の手順で開発者トークンを作成してから1時間以上後にこのコードを実行する場合、開発者トークンは60分間しか保持されないため、<Link href="/guides/mobile/ios/quick-start/configure-box-app">前の手順</Link>と同じ方法を使用して、開発者トークンを取り消して新たに生成する必要があります。
</Warning>

アプリケーションがエミュレータに読み込まれると、作成したボタンが表示されます。そのボタンをクリックしてAPIリクエストを開始します。

Xcodeの開発者コンソール内にAPIリクエストとレスポンスが表示されます。最後の行には、指定したユーザーのprintステートメントが表示されています。

```bash theme={null}
◁ Status code: 200: no error
◁ Headers:
    ◁ Cache-Control, Value: no-cache, no-store
    ◁ BOX-REQUEST-ID, Value: 1c55151238444132eca16b4c2346d005
    ◁ Transfer-Encoding, Value: Identity
    ◁ content-type, Value: application/json
    ◁ Connection, Value: keep-alive
    ◁ Strict-Transport-Security, Value: max-age=31536000
◁ Body: {"type":"user","id":"123456789","name":"Test
          User","login":"testuser@test.com"}

Authenticated as Optional("Test User")
```

<Note>
  Xcodeの開発者コンソールが表示されない場合は、メニューから \[**View (表示)**] -> \[**Debug Area (デバッグ領域)**] -> \[**Activate Console (コンソールをアクティブ化)**] をクリックします。
</Note>

これで、**Box iOS SDK**の設定が完了し、Box APIへの最初の呼び出しを実行できました。

## まとめ

* 空のiOSアプリケーションにボタンを追加しました。
* iOS SDKを使用して現在のユーザーを取得するリクエストを追加しました。

<Next>APIコールが完了しました</Next>
